fuli-context 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/web/assets/{AboutPage-CKq4IRHd.js → AboutPage-cW9hDghN.js} +1 -1
  2. package/dist/web/assets/{AgentConversations-DfXiFvBN.js → AgentConversations-CGznTWuV.js} +1 -1
  3. package/dist/web/assets/{AgentHand-BBM-sKh2.js → AgentHand-DkyF4vgk.js} +1 -1
  4. package/dist/web/assets/{AgentName-C_6R80nP.js → AgentName-C1mAVr-v.js} +1 -1
  5. package/dist/web/assets/AgentProfilePage-pKUR0rfj.js +1 -0
  6. package/dist/web/assets/AgentsDirectoryPage-CUlbT2hD.js +1 -0
  7. package/dist/web/assets/{ConnectionsPage-BoC6kXgs.js → ConnectionsPage-CuDHIJXu.js} +1 -1
  8. package/dist/web/assets/{EmployeeRecruitDialog-BVyclQAJ.js → EmployeeRecruitDialog-D9QfGipd.js} +1 -1
  9. package/dist/web/assets/{EmployeeWorkbenchPage-D2GvYraI.js → EmployeeWorkbenchPage-DAtvGney.js} +1 -1
  10. package/dist/web/assets/{KnowledgeEditDialog-a0AKWics.js → KnowledgeEditDialog-a-5rasG0.js} +1 -1
  11. package/dist/web/assets/{KnowledgeInspector-DMg9yJZ2.js → KnowledgeInspector-BGsqjNY2.js} +1 -1
  12. package/dist/web/assets/{KnowledgeOrganizerPage-BgsHM3Qw.js → KnowledgeOrganizerPage-BndgUsHS.js} +1 -1
  13. package/dist/web/assets/KnowledgePage-CQweO0YJ.js +1 -0
  14. package/dist/web/assets/{KnowledgeWorkspace-BtRq9fvC.js → KnowledgeWorkspace-BtUjKTLb.js} +1 -1
  15. package/dist/web/assets/{NotFoundPage-D-7jLz3o.js → NotFoundPage-BmQTTqQn.js} +1 -1
  16. package/dist/web/assets/{OverviewPage-BHPc-XxY.js → OverviewPage-C73HyTsM.js} +1 -1
  17. package/dist/web/assets/{PersonalProfilePage-C00iV0Kx.js → PersonalProfilePage-BMuOrppx.js} +1 -1
  18. package/dist/web/assets/PersonalProjectsPage-Cq9_kFvs.js +1 -0
  19. package/dist/web/assets/{ProjectAgentFirstTask-CrCWEYgn.js → ProjectAgentFirstTask-CaHvOjkp.js} +1 -1
  20. package/dist/web/assets/{ProjectAgentsPage-DNLNjYp-.css → ProjectAgentsPage-DWGkgIsr.css} +1 -1
  21. package/dist/web/assets/{ProjectAgentsPage-BzztLMH-.js → ProjectAgentsPage-WVcNdzVi.js} +2 -2
  22. package/dist/web/assets/{ProjectScopePicker-CMxn3txv.js → ProjectScopePicker-zAgiaZKL.js} +1 -1
  23. package/dist/web/assets/{PublicProjectsPage-DQVtvhOS.js → PublicProjectsPage-DL093f65.js} +1 -1
  24. package/dist/web/assets/{ReviewPage-BZhvyDWc.js → ReviewPage-D_NIhPx8.js} +1 -1
  25. package/dist/web/assets/{RoundtablesPage-CVebTXQa.js → RoundtablesPage-CdVVyZE-.js} +1 -1
  26. package/dist/web/assets/{SettingsPage-1knvfOW6.js → SettingsPage-CbLaau8Q.js} +1 -1
  27. package/dist/web/assets/{SharedJefaReportPage-BCVq8u0P.js → SharedJefaReportPage-aygd6wvb.js} +1 -1
  28. package/dist/web/assets/{UiDialog-Da1P10f4.js → UiDialog-Q7fsJUoO.js} +1 -1
  29. package/dist/web/assets/{UiDisclosure-8wE8YuE4.js → UiDisclosure-BS-muK5j.js} +1 -1
  30. package/dist/web/assets/{UiSegmented-BKZXc8QF.js → UiSegmented-CT28bxqw.js} +1 -1
  31. package/dist/web/assets/{UiSelect-D5Xj5Ec4.js → UiSelect-DcGpPQQo.js} +1 -1
  32. package/dist/web/assets/{WritingTastePage-B8-etOBn.js → WritingTastePage-CYlwAFqV.js} +1 -1
  33. package/dist/web/assets/{attention-store-BfxtL9EV.js → attention-store-D-qIFRIb.js} +1 -1
  34. package/dist/web/assets/{catalog-6SN9i3WR.js → catalog-UDv854JN.js} +1 -1
  35. package/dist/web/assets/{client-CUTkF3t4.js → client-DLS5FZBI.js} +1 -1
  36. package/dist/web/assets/{console-CG8tdtSs.js → console-CqzwSo7a.js} +1 -1
  37. package/dist/web/assets/{conversation-launcher-settings-CyZkLJg7.js → conversation-launcher-settings-DRoIz42V.js} +1 -1
  38. package/dist/web/assets/{i18n-CCMR4gDS.js → i18n-b14l2pQA.js} +2 -2
  39. package/dist/web/assets/{identity-C1eN-FSB.js → identity-BWbPmZZf.js} +1 -1
  40. package/dist/web/assets/{index-sLDKI6R-.js → index-D1OHIz4c.js} +3 -3
  41. package/dist/web/assets/{model-l-sAqtW_.js → model-DupZy8Qb.js} +1 -1
  42. package/dist/web/assets/{personal-profile-graph-BD1Y6TDS.js → personal-profile-graph-BPTtMJTZ.js} +1 -1
  43. package/dist/web/assets/{shared-report-B46dxlCR.js → shared-report-BYnLhmCZ.js} +1 -1
  44. package/dist/web/assets/{useAgentRoster-DdxoKDEE.js → useAgentRoster-ep7SpKv1.js} +1 -1
  45. package/dist/web/assets/{useApi-CROJJdhE-DlOiu8lP.js → useApi-CROJJdhE-CEQAEuug.js} +1 -1
  46. package/dist/web/assets/{vue-router-DjqEU4W2.js → vue-router-B6ZjK-Br.js} +1 -1
  47. package/dist/web/index.html +11 -11
  48. package/docs/agent-roundtable.md +17 -1
  49. package/graph-provider/fuli_graph/project_agent_context_models.py +5 -1
  50. package/graph-provider/fuli_graph/project_agent_delegations.py +118 -0
  51. package/graph-provider/fuli_graph/project_agent_employee_numbers.py +41 -0
  52. package/graph-provider/fuli_graph/project_agent_memory_routes.py +13 -0
  53. package/graph-provider/fuli_graph/project_agent_models.py +1 -0
  54. package/graph-provider/fuli_graph/project_agent_team_growth.py +2 -2
  55. package/graph-provider/fuli_graph/runtime.py +7 -0
  56. package/graph-provider/fuli_graph/store_project_agent_context.py +52 -4
  57. package/graph-provider/fuli_graph/store_project_agent_coordination_policy.py +16 -1
  58. package/graph-provider/fuli_graph/store_project_agent_task_staffing.py +3 -2
  59. package/graph-provider/fuli_graph/store_project_agents.py +31 -5
  60. package/graph-provider/fuli_graph/system_agents.py +3 -1
  61. package/graph-provider/pyproject.toml +1 -1
  62. package/npm-shrinkwrap.json +2 -2
  63. package/package.json +1 -1
  64. package/src/agent-roundtable/service.js +34 -5
  65. package/src/agent-roundtable/wake.js +2 -1
  66. package/src/agents/identity-receipt.js +20 -2
  67. package/src/graphiti/federated-application.js +5 -1
  68. package/src/graphiti/project-agent-mapping.js +2 -0
  69. package/src/graphiti/project-agent-task-entry.js +21 -3
  70. package/src/graphiti/project-agent-team-context.js +4 -1
  71. package/src/graphiti/provider-client.js +9 -0
  72. package/src/graphiti/task-entry-preferences.js +12 -4
  73. package/src/graphiti/task-entry-project-scope.js +67 -0
  74. package/dist/web/assets/AgentProfilePage-Cz-i1fRD.js +0 -1
  75. package/dist/web/assets/AgentsDirectoryPage-BI0EFz6y.js +0 -1
  76. package/dist/web/assets/KnowledgePage-kn8MqUCO.js +0 -1
  77. package/dist/web/assets/PersonalProjectsPage-CFNkdHSo.js +0 -1
@@ -33,10 +33,11 @@ export function sessionWorkingDirectory(client, sessionId, { home = homedir(), e
33
33
  }
34
34
 
35
35
  export async function wakeAgent({ client, sessionId = null, cwd, prompt, timeoutMs = 300_000,
36
- env = process.env, run = runProcess } = {}) {
36
+ delegationToken = null, env = process.env, run = runProcess } = {}) {
37
37
  const command = resolveClientCommand(client, { env });
38
38
  if (!command) throw Object.assign(new Error(`${client} is not installed on this machine`), { code: 'client_unavailable' });
39
39
  const childEnv = Object.fromEntries(Object.entries(env).filter(([key]) => !key.startsWith('FULI_ROUNDTABLE_')));
40
+ if (delegationToken) childEnv.FULI_ROUNDTABLE_DELEGATION = delegationToken;
40
41
  const result = await run(command, wakeArguments(client, { sessionId, cwd }), { cwd, env: childEnv, input: prompt, timeoutMs });
41
42
  return parseFinalAnswer(client, result);
42
43
  }
@@ -22,14 +22,14 @@ function agentLink(application, agentId, name) {
22
22
  // The reply's attribution line: who led the task and who actually helped.
23
23
  export function taskAgentReceipt(application, { projectId, agentId, name = null,
24
24
  sourceApplication = null, workStatus = null, conversationId = null, persistence = null,
25
- collaborators = [] }) {
25
+ collaborators = [], assignmentStatus = null, assignmentReason = null }) {
26
26
  const owner = agentId ? { agent_id: agentId, name,
27
27
  profile_url: agentProfileUrl(application, agentId), source_application: sourceApplication } : null;
28
28
  const helpers = owner ? collaborators.filter(item => item.agentId !== agentId) : [];
29
29
  const markdown = owner
30
30
  ? `FULI Agent:负责人 ${agentLink(application, agentId, name)}`
31
31
  + (helpers.length ? ` · 协作 ${helpers.map(item => agentLink(application, item.agentId, item.name)).join('、')}` : '')
32
- : 'FULI Agent:未选定';
32
+ : unassignedReceipt(assignmentStatus, assignmentReason);
33
33
  return { required: true, markdown, owner,
34
34
  collaborators: helpers.map(item => ({ agent_id: item.agentId, name: item.name,
35
35
  profile_url: agentProfileUrl(application, item.agentId) })),
@@ -38,6 +38,24 @@ export function taskAgentReceipt(application, { projectId, agentId, name = null,
38
38
  guidance: 'MUST end every final user-visible reply with agent_receipt.markdown unchanged, exactly once, including greetings, status and errors, even when capture is disabled or nothing is retained. The receipt returned by checkpoint_task_knowledge supersedes the entry receipt because it names actual collaborators. Never invent an owner or a collaborator.' };
39
39
  }
40
40
 
41
+ function unassignedReceipt(status, reason) {
42
+ if (!status) return 'FULI Agent:分配未完成(任务没有可用负责人)';
43
+ if (status === 'project_unresolved') {
44
+ return reason === 'ambiguous' ? 'FULI Agent:分配待确认(项目归属待确认)'
45
+ : reason === 'session_identity_required' ? 'FULI Agent:分配失败(缺少会话标识)'
46
+ : 'FULI Agent:分配失败(项目归属未能恢复)';
47
+ }
48
+ const labels = {
49
+ unavailable: '分配失败(服务或身份恢复不可用)',
50
+ agent_unavailable: '分配失败(指定 FLA 不可用)',
51
+ agent_not_found: '分配失败(指定 FLA 不存在)',
52
+ ambiguous_agent: '分配待确认(存在同名 FLA)',
53
+ agent_selection_conflict: '分配待确认(FLA 选择冲突)',
54
+ manual_selection: '分配待确认(需要选择负责人)'
55
+ };
56
+ return `FULI Agent:${labels[status] ?? '分配未完成(HR 尚未返回负责人)'}`;
57
+ }
58
+
41
59
  export function employeeCollaborationReceipt(application, context, { tool, permission, sourceApplication }) {
42
60
  return { agent_id: context.agentId, name: context.name, role: context.role,
43
61
  profile_url: agentProfileUrl(application, context.agentId),
@@ -81,6 +81,7 @@ import {
81
81
  import { buildUserTasteSkill } from './user-taste-skill.js';
82
82
  import { taskEntryPreferences } from './task-entry-preferences.js';
83
83
  import { TASK_ENTRY_TOOLS, registerRepositoryProject } from './repository-project-registration.js';
84
+ import { resolveTaskEntryProject } from './task-entry-project-scope.js';
84
85
  import { getWritingTasteProfile as getWritingTasteProfileWorkflow } from './writing-taste-profile-workflow.js';
85
86
  import {
86
87
  groupSubscriptions,
@@ -119,7 +120,7 @@ export function openFederatedGraphApplication({
119
120
  fetchImpl
120
121
  });
121
122
  app.employees = createEmployeeService({ app, runtimeConfigPath });
122
- app.roundtable = createAgentRoundtable({ app,
123
+ app.roundtable = createAgentRoundtable({ app, env,
123
124
  openStore: () => createRoundtableStore(join(dirname(runtimeConfigPath), 'agent-roundtable.sqlite')) });
124
125
  }
125
126
  return app;
@@ -267,6 +268,9 @@ export class FederatedGraphApplication extends ProjectAgentControlPlaneApplicati
267
268
  // Every task gets a FULI Agent, so a task in an unregistered repository registers it.
268
269
  projectResolution = await registerRepositoryProject(this, projectResolution);
269
270
  }
271
+ projectResolution = await resolveTaskEntryProject(this, projectResolution, {
272
+ sessionId, sourceSessionId, sourceApplication, agentInvocation, agentToolName
273
+ });
270
274
  return taskEntryPreferences(this, projectResolution, {
271
275
  personalProjectId, projectAgentId, projectPath, taskPrompt, sourceApplication,
272
276
  sourceSessionId, sessionId, turnId, workKind, requiredCapabilities,
@@ -71,6 +71,8 @@ export function projectAgentRecord(value) {
71
71
  Object.hasOwn(profile, 'display_name'));
72
72
  copyOptional(result, 'legacyAgentIds', value.legacy_agent_ids,
73
73
  Object.hasOwn(value, 'legacy_agent_ids'));
74
+ copyOptional(result, 'employeeNumber', value.employee_number,
75
+ Object.hasOwn(value, 'employee_number'));
74
76
  copyOptional(result.profile, 'workKinds', profile.work_kinds,
75
77
  Object.hasOwn(profile, 'work_kinds'));
76
78
  copyOptional(
@@ -8,7 +8,11 @@ const ENTRY_TOOLS = new Set(['begin_task_context', 'get_collaboration_preference
8
8
 
9
9
  export async function resolveTaskEntryAgent(application, resolution, input) {
10
10
  if (!input.agentInvocation || !ENTRY_TOOLS.has(input.agentToolName)) return null;
11
- if (!resolution.personalProjectId) return { status: 'project_unresolved', worker_started: false };
11
+ if (!resolution.personalProjectId) return {
12
+ status: resolution.status === 'unavailable' ? 'unavailable' : 'project_unresolved',
13
+ reason: resolution.reason ?? resolution.status,
14
+ worker_started: false
15
+ };
12
16
  try {
13
17
  const mention = await resolveTaskAgentMention(application, resolution.personalProjectId, input);
14
18
  if (mention?.status) return mention;
@@ -18,19 +22,33 @@ export async function resolveTaskEntryAgent(application, resolution, input) {
18
22
  personal_project_id: resolution.personalProjectId,
19
23
  source_application: input.sourceApplication ?? 'other'
20
24
  };
21
- let value = await application.personal.resolveProjectAgentContext({
25
+ const contextRequest = {
22
26
  ...scope,
23
27
  agent_id: mention?.agentId ?? input.projectAgentId ?? null,
24
28
  session_id: input.sessionId ?? null,
25
29
  turn_id: input.turnId ?? null,
26
30
  work_kind: workKind,
27
31
  required_capabilities: input.requiredCapabilities ?? []
32
+ };
33
+ const delegation = application.roundtable?.taskEntryDelegation?.({
34
+ sessionId: input.receivingSessionId ?? input.sessionId
28
35
  });
36
+ if (delegation) {
37
+ contextRequest.delegation_token = delegation.token;
38
+ contextRequest.delegation_session_id = delegation.sessionId;
39
+ }
40
+ let value = await application.personal.resolveProjectAgentContext(contextRequest);
41
+ if (value?.reason === 'project_lead_required') {
42
+ await application.personal.staffDefaultProjectLead(scope);
43
+ // Re-resolve after staffing so a requested specialist is not lost and a
44
+ // concurrent successful hire is handled without selecting another owner.
45
+ value = await application.personal.resolveProjectAgentContext(contextRequest);
46
+ }
29
47
  if (!value?.status) throw new Error('Role resolution is unavailable');
30
48
  let agent = value.agent ? projectAgentRecord(value.agent) : null;
31
49
  const implicit = !mention?.agentId && !input.projectAgentId;
32
50
  const peerOnly = agent && implicit && unrelatedPeer(agent, workKind, input.requiredCapabilities);
33
- if (implicit && (peerOnly || value.status === 'unassigned')) {
51
+ if (implicit && value.reason !== 'project_lead_required' && (peerOnly || value.status === 'unassigned')) {
34
52
  // Every task gets a FULI Agent: a project without a lead has HR hire one.
35
53
  const staffed = await application.personal.staffDefaultProjectLead(scope).catch(() => null);
36
54
  if (staffed?.agent) {
@@ -15,7 +15,10 @@ export async function loadProjectTeamContext(application, personalSpaceId, proje
15
15
  && assignment.status === 'active')?.responsibility || agent.profile?.responsibility,
16
16
  role: agent.agent_id === policy.team_lead_agent_id ? 'lead' : 'member' }));
17
17
  return { lead_agent_id: policy.team_lead_agent_id, roster,
18
+ user_facing_agent_id: policy.team_lead_agent_id,
19
+ reporting_lines: roster.filter(agent => agent.role === 'member')
20
+ .map(agent => ({ agent_id: agent.agent_id, reports_to_agent_id: policy.team_lead_agent_id })),
18
21
  unavailable_agent_ids: ids.filter(id => !roster.some(agent => agent.agent_id === id)),
19
22
  peer_roles: ['hr', 'project_manager'], worker_started: false,
20
- guidance: 'The team lead is the user-facing owner. Split bounded work among team members through an authorized coordination plan; report real worker evidence. HR and project managers remain peers. Team membership grants no new tool, data, executor, or publication permissions.' };
23
+ guidance: 'The project lead is the sole user-facing owner. Members report results and blockers to this lead; do not skip reporting levels or replace the lead when a member is named. The lead integrates and verifies member reports before reporting to the user. Split bounded work through an authorized coordination plan; report real worker evidence. HR and project managers remain peers. Team membership grants no new tool, data, executor, or publication permissions.' };
21
24
  }
@@ -153,6 +153,15 @@ export class GraphitiProviderClient {
153
153
  resolveProjectAgentContext(input) {
154
154
  return this.#request('/v1/project-agent-context/resolve', { method: 'POST', body: input });
155
155
  }
156
+ issueAgentDelegation(input) {
157
+ return this.#request('/v1/project-agent-context/delegations', { method: 'POST', body: input });
158
+ }
159
+ verifyAgentDelegation(input) {
160
+ return this.#request('/v1/project-agent-context/delegations/verify', { method: 'POST', body: input });
161
+ }
162
+ revokeAgentDelegation(input) {
163
+ return this.#request('/v1/project-agent-context/delegations/revoke', { method: 'POST', body: input });
164
+ }
156
165
  recentAgentSessions({ personalSpaceId, agentId, personalProjectId = null, limit = 5 }) {
157
166
  const query = new URLSearchParams({ personal_space_id: personalSpaceId, project_agent_id: agentId, limit: String(limit) });
158
167
  if (personalProjectId) query.set('personal_project_id', personalProjectId);
@@ -7,12 +7,11 @@ export async function taskEntryPreferences(application, projectResolution, {
7
7
  sourceSessionId, sessionId, turnId, workKind, requiredCapabilities,
8
8
  limit, agentInvocation, agentToolName
9
9
  }, recordAgentViews) {
10
- const selection = projectPath === null && !personalProjectId && !projectAgentId
11
- ? null
12
- : await resolveTaskEntryAgent(
10
+ const selection = await resolveTaskEntryAgent(
13
11
  application, projectResolution, { projectAgentId, taskPrompt, sourceApplication,
14
12
  sessionId: agentToolName === 'get_collaboration_preferences'
15
13
  ? sessionId ?? sourceSessionId : turnId ? sessionId : null,
14
+ receivingSessionId: sessionId ?? sourceSessionId,
16
15
  turnId: agentToolName === 'begin_task_context' ? turnId : null,
17
16
  workKind, requiredCapabilities, agentInvocation, agentToolName }
18
17
  );
@@ -41,6 +40,14 @@ export async function taskEntryPreferences(application, projectResolution, {
41
40
  sourceApplication, taskPrompt, selectionReason: selection.reason,
42
41
  matchBasis: selection.match_basis
43
42
  }) : selection;
43
+ if (context && selection?.requested_agent_id) {
44
+ context.requested_agent_id = selection.requested_agent_id;
45
+ context.requested_agent_guidance = 'The user requested this project specialist. Keep the project lead as accountable owner; coordinate a scoped workstream for the specialist and receive its report before replying. This request is not evidence that a worker ran. Do not load the specialist’s private memory into the lead context.';
46
+ }
47
+ if (context && selection?.reporting_lead_agent_id) {
48
+ context.reporting_lead_agent_id = selection.reporting_lead_agent_id;
49
+ context.reporting_guidance = 'This is a delegated member turn. Keep this member identity and private memory isolated. Return results and blockers to the project lead; the lead integrates the final user report.';
50
+ }
44
51
  // Questions other Agents left for this Agent while it was not running.
45
52
  const waiting = selection?.agent && application.roundtable
46
53
  ? application.roundtable.pending(selection.agent.agentId) : [];
@@ -49,6 +56,7 @@ export async function taskEntryPreferences(application, projectResolution, {
49
56
  agent_messages_guidance: 'Other Agents are waiting for your answers. Reply to each with reply_agent_message.' } : {}),
50
57
  agent_receipt: taskAgentReceipt(application, {
51
58
  projectId: projectResolution.personalProjectId, agentId: selection?.agent?.agentId ?? null,
52
- name: context?.role?.name, sourceApplication
59
+ name: context?.role?.name, sourceApplication,
60
+ assignmentStatus: selection?.status, assignmentReason: selection?.reason
53
61
  }) };
54
62
  }
@@ -0,0 +1,67 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { TASK_ENTRY_TOOLS } from './repository-project-registration.js';
3
+
4
+ // Restore only exact session provenance; a normal folder name is not a role binding.
5
+ // The fallback scope is private and contains no prompt, path or raw session identity.
6
+ export async function resolveTaskEntryProject(application, resolution, input) {
7
+ if (!input.agentInvocation || !TASK_ENTRY_TOOLS.has(input.agentToolName)
8
+ || resolution.personalProjectId || resolution.repositoryProjectId
9
+ || !['unmatched', 'not_provided'].includes(resolution.status)) return resolution;
10
+ // A known native session is stronger than an MCP process ID. Never use an
11
+ // older process assignment to override a different, explicitly known chat.
12
+ const identity = input.sessionId ?? input.sourceSessionId;
13
+ const sessions = typeof identity === 'string' && identity.trim() ? [identity] : [];
14
+ if (!sessions.length) return { ...resolution, reason: 'session_identity_required' };
15
+ const spaceId = application.config.personal.spaceId;
16
+ const source = input.sourceApplication ?? 'other';
17
+ try {
18
+ for (const sessionId of sessions) {
19
+ const context = await application.taskContextRegistry?.current?.(sessionId, source);
20
+ if (!context?.personalProjectId || context.projectScope?.type === 'temporary') continue;
21
+ const project = await application.personal.getPersonalProject(spaceId, context.personalProjectId);
22
+ if (project?.scope_type !== 'temporary') {
23
+ return matched(context.personalProjectId, 'host_session_context');
24
+ }
25
+ }
26
+ const assignments = await application.personal.listProjectAgentAssignments({
27
+ personalSpaceId: spaceId, status: 'active'
28
+ });
29
+ const candidates = [...new Set(assignments.filter(value => value.status === 'active'
30
+ && (!value.personal_space_id || value.personal_space_id === spaceId)
31
+ && value.source_application === source && sessions.includes(value.source_session_id))
32
+ .map(value => value.personal_project_id).filter(Boolean))];
33
+ const registered = [];
34
+ for (const id of candidates) {
35
+ const project = await application.personal.getPersonalProject(spaceId, id);
36
+ if (project?.scope_type !== 'temporary') registered.push(id);
37
+ }
38
+ if (registered.length > 1) {
39
+ return { status: 'ambiguous', basis: 'host_session_assignment',
40
+ personalProjectId: null, candidateCount: registered.length };
41
+ }
42
+ if (registered.length === 1) return matched(registered[0], 'host_session_assignment');
43
+
44
+ const key = createHash('sha256').update(JSON.stringify([
45
+ 'fuli-conversation-project-v1', spaceId, source, sessions[0]
46
+ ])).digest('hex');
47
+ const projectId = `conversation-${key}`;
48
+ try {
49
+ await application.personal.getPersonalProject(spaceId, projectId);
50
+ } catch (error) {
51
+ if (error.status !== 404) throw error;
52
+ await application.upsertPersonalProject({ personalSpaceId: spaceId, projectId,
53
+ profile: { name: '会话项目 / Conversation project', lifecycle: 'active',
54
+ purpose: '为尚未归属已有项目的会话提供独立的负责人和上下文。',
55
+ boundaries: ['仅供当前会话使用,不隐式继承其他项目知识。'] } });
56
+ }
57
+ return matched(projectId, 'isolated_conversation');
58
+ } catch {
59
+ // A failed read cannot prove that no previous owner exists.
60
+ return { status: 'unavailable', basis: null, personalProjectId: null,
61
+ reason: 'session_scope_unavailable' };
62
+ }
63
+ }
64
+
65
+ function matched(personalProjectId, basis) {
66
+ return { status: 'matched', basis, personalProjectId };
67
+ }
@@ -1 +0,0 @@
1
- import{B as e,C as t,M as n,P as r,R as i,S as a,V as o,X as s,_ as c,a as l,b as u,d,g as f,it as p,j as m,k as ee,m as h,nt as g,p as te,tt as _,u as v,v as y,w as b,y as x}from"./i18n-CCMR4gDS.js";import{t as S}from"./console-CG8tdtSs.js";import{a as C,n as w,o as T}from"./client-CUTkF3t4.js";import{m as E}from"./useApi-CROJJdhE-DlOiu8lP.js";import{t as D}from"./vue-router-DjqEU4W2.js";import{t as O}from"./UiSelect-D5Xj5Ec4.js";import{t as k}from"./UiDisclosure-8wE8YuE4.js";import{n as A}from"./paths-CDREouhi.js";import{a as j,r as M,t as N}from"./profile-model-BQO4zNs9.js";import{t as P}from"./AgentName-C_6R80nP.js";import{t as ne}from"./AgentConversations-DfXiFvBN.js";import{d as re,i as F,m as ie,r as ae,t as oe,v as se,w as ce}from"./agent-work-summary-LeW-Al_S.js";import{t as le}from"./useAgentRoster-DdxoKDEE.js";import{a as ue}from"./catalog-6SN9i3WR.js";/* empty css */var I={key:1,class:`agent-locked-platforms`},L={key:2,class:`agent-platform-field`},de=[`disabled`,`placeholder`],R=[`onUpdate:modelValue`,`disabled`],fe={key:3,role:`alert`},pe={key:4,role:`status`},z=[`disabled`],me=b({__name:`AgentProfileSettings`,props:{agent:{}},emits:[`saved`],setup(e,{emit:d}){let m=e,ee=d,g=s([]),b=s(!1),S=s(!1),E=s(``),D=s(!1),k=``,A=s(``),j=s(``),M=s({judgment:``,taste:``,personality:``}),N=f(()=>m.agent.profile.executorPolicy?.mode===`locked`),P=f(()=>{let e=m.agent.profile.executorPolicy;return(e?.lockedExecutorIds?.length?e.lockedExecutorIds:(e?.allowList??[]).map(e=>e.executorId)).map(e=>g.value.find(t=>t.executorId===e)?.displayName||e)}),ne=f(()=>g.value.filter(e=>e.registrationStatus===`registered`&&e.permissionStatus===`authorized`&&e.preflightStatus===`passed`&&e.workspacePermission&&e.healthStatus!==`unhealthy`&&(!e.healthRequired||e.healthStatus===`healthy`))),re=f(()=>[{value:``,label:l(`agentProfiles.automatic`)},...A.value&&!ne.value.some(e=>e.executorId===A.value)?[{value:A.value,label:l(`agentProfiles.platformUnavailable`),disabled:!0}]:[],...ne.value.map(e=>({value:e.executorId,label:e.displayName||e.executorId}))]),F=0;i(()=>`${m.agent.personalSpaceId}/${m.agent.agentId}`,async()=>{let e=m.agent,t=++F;j.value=e.profile.expectations??``,M.value={judgment:``,taste:``,personality:``,...e.profile.character},A.value=e.profile.executorPolicy?.preferredExecutorIds?.[0]??``,k=A.value,E.value=``,D.value=!1,S.value=!1,b.value=!0,g.value=[];try{let n=await w(`/api/executors?${new URLSearchParams({personalSpaceId:e.personalSpaceId})}`);t===F&&(g.value=Array.isArray(n)?n:n.executors)}catch{t===F&&(E.value=l(`agentProfiles.platformUnavailable`))}finally{t===F&&(b.value=!1)}},{immediate:!0});async function ie(){if(S.value)return;let e=F,t=m.agent;S.value=!0,E.value=``,D.value=!1;let n=t.profile.executorPolicy;try{let r=await C(`/api/project-agents`,{personalSpaceId:t.personalSpaceId,personalProjectId:t.personalProjectId??null,agentId:t.agentId,profile:{...t.profile,character:{...M.value},expectations:j.value,executorPolicy:N.value||A.value===k?n:{...n,mode:`flexible`,preferredExecutorIds:A.value?[A.value]:[]}}});e===F&&(k=A.value,ee(`saved`,r),D.value=!0)}catch(t){e===F&&(E.value=t instanceof Error?t.message:l(`agentProfiles.saveError`))}finally{e===F&&(S.value=!1)}}return(e,i)=>(n(),u(`form`,{class:`agent-simple-settings`,onSubmit:te(ie,[`prevent`])},[c(`h3`,null,p(_(l)(`agentProfiles.settings`)),1),b.value?(n(),y(T,{key:0,variant:`compact`,label:_(l)(`agentProfiles.settingsLoading`)},null,8,[`label`])):N.value?(n(),u(`div`,I,[c(`h4`,null,p(_(l)(`agentProfiles.platform`)),1),c(`p`,null,p(P.value.join(` · `)||_(l)(`agentProfiles.platformUnavailable`)),1),c(`small`,null,p(_(l)(`agentProfiles.locked`)),1)])):(n(),u(`div`,L,[t(O,{modelValue:A.value,"onUpdate:modelValue":i[0]||=e=>A.value=e,field:``,label:_(l)(`agentProfiles.platform`),options:re.value,disabled:N.value||S.value},null,8,[`modelValue`,`label`,`options`,`disabled`]),c(`small`,null,p(_(l)(N.value?`agentProfiles.locked`:`agentProfiles.platformHint`)),1)])),c(`label`,null,[a(p(_(l)(`agentProfiles.expectations`)),1),o(c(`textarea`,{"onUpdate:modelValue":i[1]||=e=>j.value=e,rows:`3`,maxlength:`4096`,disabled:S.value,placeholder:_(l)(`agentProfiles.expectationsPlaceholder`)},null,8,de),[[v,j.value]])]),c(`details`,null,[c(`summary`,null,p(_(l)(`agentProfiles.editCharacter`)),1),(n(),u(h,null,r([`judgment`,`taste`,`personality`],e=>c(`label`,{key:e},[a(p(_(l)(`agentProfiles.${e}`)),1),o(c(`textarea`,{"onUpdate:modelValue":t=>M.value[e]=t,rows:`2`,maxlength:`2048`,disabled:S.value},null,8,R),[[v,M.value[e]]])])),64))]),E.value?(n(),u(`p`,fe,p(E.value),1)):x(``,!0),D.value?(n(),u(`p`,pe,p(_(l)(`agentProfiles.saved`)),1)):x(``,!0),c(`button`,{class:`primary-button`,disabled:S.value||b.value,type:`submit`},[S.value?(n(),y(T,{key:0,variant:`inline`,label:_(l)(`agentProfiles.saving`)},null,8,[`label`])):(n(),u(h,{key:1},[a(p(_(l)(`agentProfiles.save`)),1)],64))],8,z)],32))}}),he=[`aria-label`],ge={key:1,class:`ui-card ui-empty agent-profile-empty`,role:`alert`},_e={key:2,class:`ui-card ui-empty agent-profile-empty`},ve={class:`ui-card agent-resume-header`},ye={class:`agent-portrait`,"aria-hidden":`true`},be={class:`agent-resume-intro`},xe={class:`agent-resume-name-row`},Se={class:`agent-resume-meta`},Ce={class:`agent-profile-actions`},we=[`aria-expanded`],Te={key:1,class:`agent-profile-refresh-status`,role:`status`},Ee=[`aria-label`],De=[`id`,`aria-selected`,`aria-controls`,`tabindex`,`onClick`,`onKeydown`],Oe={key:4,class:`agent-profile-partial`,role:`status`},ke=[`aria-hidden`],Ae={class:`agent-profile-primary-grid`},je={class:`ui-card agent-resume-section agent-current-work-section`},Me={class:`agent-section-heading`},Ne={key:0},Pe={key:0,class:`agent-current-work-list`},Fe={class:`ui-badge`},Ie={key:1,class:`agent-muted`},Le={key:2,class:`agent-muted`},Re={class:`ui-card agent-resume-section agent-projects-section`},ze={class:`agent-section-heading`},Be={class:`agent-resume-list agent-current-project-list`},Ve={key:0,class:`agent-project-responsibility`},He={class:`agent-resume-list`},Ue={key:0,class:`agent-project-responsibility`},We={key:1,class:`agent-muted`},Ge=[`aria-hidden`],Ke={class:`ui-card agent-resume-section`},qe={key:0,class:`ui-disclosure`,open:``},Je={class:`agent-resume-list`},Ye={key:1,class:`agent-muted`},Xe={class:`ui-card agent-resume-section`},Ze={class:`agent-muted`},Qe={class:`agent-work-timeline`},$e={class:`agent-section-heading`},et={key:0},tt={key:0},nt={key:0},rt={key:0,class:`agent-muted`},it=[`aria-hidden`],at={class:`ui-card agent-resume-section`},ot={class:`agent-character`},st={key:0,class:`agent-expectation`},ct={class:`agent-strengths`},lt={class:`agent-inline-skills`},ut={key:0},dt=[`aria-hidden`],ft={class:`ui-card agent-resume-section`},pt={class:`agent-section-heading`},mt={key:0,role:`status`},ht={key:0,class:`agent-org-lead`},gt={key:1,class:`agent-org-members`},_t={key:2,class:`agent-muted`},vt={key:0,class:`agent-muted`},yt={class:`ui-card agent-resume-section`},bt={class:`agent-collaborators`},xt={key:0,class:`agent-muted`},St=[`aria-hidden`],Ct={class:`ui-card agent-resume-section`},wt=[`aria-hidden`],Tt={class:`ui-card agent-resume-section agent-management-card`},Et={class:`agent-muted`},Dt={class:`agent-profile-management-links`},Ot={class:`agent-profile-footer`},B=b({__name:`AgentProfilePage`,setup(te){let v=E(),b=S(),C=f(()=>b.activePersonalSpace?.id??``),{agents:O,loading:I,error:L,load:de}=le(C),R=f(()=>v.params.spaceId===C.value?O.value.find(e=>e.personalSpaceId===C.value&&(e.agentId===v.params.agentId||e.legacyAgentIds?.includes(String(v.params.agentId)))):void 0),fe=f(()=>(b.state?.personalProjects??[]).filter(e=>e.personal_space_id===C.value)),pe=f(()=>fe.value.map(e=>({id:e.project_id,name:e.profile.name}))),z=e=>fe.value.find(t=>t.project_id===e)?.profile.name||e,B=e=>{let t=O.value.find(t=>t.agentId===e);return t?N(t):e},V=s([]),H=s(void 0),U=s([]),W=s(!1),G=s(!1),K=s(!1),q=s(`overview`),J=f(()=>{let e=[{id:`overview`,label:l(`agentProfiles.working`)},{id:`history`,label:l(`agentProfiles.experience`)},{id:`style`,label:l(`agentProfiles.about`)},{id:`collaborators`,label:l(`agentProfiles.collaborators`)},{id:`management`,label:l(`agentProfiles.advanced`)}];return R.value?.memoryScope===`reviewed_agent`&&e.splice(4,0,{id:`conversations`,label:l(`projectAgents.conversations.title`)}),e}),kt=f(()=>R.value?M(R.value.agentId,V.value):[]),Y=f(()=>R.value?j({...R.value,assignments:H.value??R.value.assignments}):[]),At=f(()=>Y.value.slice(0,4)),jt=f(()=>Y.value.slice(4)),Mt=f(()=>(H.value??[]).filter(e=>e.status!==`active`)),X=f(()=>V.value.filter(e=>F.has(e.status)).slice(0,6)),Z=f(()=>ue.value.find(e=>e.agentId===R.value?.agentId)),Q=e=>e&&!Number.isNaN(Date.parse(e))?new Date(e).toLocaleDateString():l(`agentProfiles.timeUnknown`),$=e=>{let t=H.value?.find(t=>t.personalProjectId===e&&t.status===`active`)?.responsibility?.trim(),n=R.value?.profile.responsibility.trim();return t&&t!==n?t:``},Nt=f(()=>{let e=`agentRedesign.projects.more`,t=l(e,{count:Y.value.length});return t===e?`All projects (${Y.value.length})`:t}),Pt=0;i(()=>R.value?`${R.value.personalSpaceId}/${R.value.agentId}`:``,async()=>{let e=R.value,t=++Pt;if(V.value=[],H.value=void 0,U.value=[],G.value=!1,W.value=!1,K.value=!1,q.value=`overview`,!e)return;W.value=!0,H.value=e.assignments;let n=new URLSearchParams({personalSpaceId:e.personalSpaceId}),r=new URLSearchParams({personalSpaceId:e.personalSpaceId,agentId:e.agentId}),i=await Promise.allSettled([w(`/api/project-agent-tasks?${n}&limit=200`),w(`/api/project-agent-assignments?${r}`)]);if(t!==Pt)return;let[a,o]=i;if(a.status===`fulfilled`){let t=a.value,n=ce(t);G.value=!oe(t),V.value=re(Array.isArray(t)?t:n.tasks??n.items).map(se).filter(t=>!!(t&&(!t.personalSpaceId||t.personalSpaceId===e.personalSpaceId)&&ae(t,e.agentId))).sort((e,t)=>(t.updatedAt??t.createdAt??``).localeCompare(e.updatedAt??e.createdAt??``))}else G.value=!0;if(o.status===`fulfilled`){let t=o.value,n=ce(t);H.value=re(Array.isArray(t)?t:n.assignments??n.items).map(t=>ie(t,e)).filter(t=>!!(t&&t.agentId===e.agentId&&t.personalSpaceId===e.personalSpaceId))}else G.value=!0;let s=j({...e,assignments:H.value??e.assignments}),c=await Promise.all(s.map(async t=>{try{return{projectId:t,policy:await w(`/api/project-agent-coordination-policy?${new URLSearchParams({personalSpaceId:e.personalSpaceId,personalProjectId:t})}`),error:!1}}catch{return{projectId:t,policy:null,error:!0}}}));t===Pt&&(U.value=c,W.value=!1)},{immediate:!0});function Ft(e){let t=O.value.findIndex(t=>t.agentId===e.agentId);t>=0&&(O.value[t]={...O.value[t],...e})}function It(e){q.value=e}function Lt(e,t){let n=e.key;if(![`ArrowLeft`,`ArrowRight`,`Home`,`End`].includes(n))return;let r=e.currentTarget;e.preventDefault();let i=J.value.length,a=n===`Home`?0:n===`End`?i-1:(t+(n===`ArrowRight`?1:-1)+i)%i,o=J.value[a];o&&(It(o.id),ee(()=>{let e=(r?.closest(`[role="tablist"]`))?.querySelectorAll(`[role="tab"]`)[a];e?.focus(),e?.scrollIntoView?.({block:`nearest`,inline:`nearest`})}))}return m(()=>{b.runtimeStatus===`idle`&&b.refresh()}),(i,s)=>(n(),u(`section`,{class:`view agent-profile-page`,"aria-label":_(l)(`agentProfiles.profile`)},[t(_(D),{class:`agent-profile-back`,to:`/project-agents`},{default:e(()=>[a(` ← `+p(_(l)(`agentProfiles.back`)),1)]),_:1}),(_(I)||_(b).runtimeStatus===`loading`)&&!R.value?(n(),y(T,{key:0,label:_(l)(`agentProfiles.loading`)},null,8,[`label`])):(_(L)||_(b).runtimeStatus===`error`)&&!R.value?(n(),u(`div`,ge,[c(`p`,null,p(_(L)||_(l)(`agentProfiles.loadError`)),1),c(`button`,{class:`quiet-button`,type:`button`,onClick:s[0]||=e=>_(b).state?_(de)():_(b).refresh()},p(_(l)(`agentProfiles.retry`)),1)])):R.value?(n(),u(h,{key:3},[c(`header`,ve,[c(`span`,ye,p(R.value.profile.occupationEmoji||_(N)(R.value).slice(0,1)),1),c(`div`,be,[c(`div`,xe,[c(`h1`,null,p(_(N)(R.value)),1),c(`span`,{class:g([`ui-badge agent-profile-membership`,`is-${R.value.profile.status}`])},p(_(l)(`projectAgents.status.${R.value.profile.status}`)),3)]),c(`p`,null,p(R.value.profile.responsibility),1),c(`div`,Se,[c(`span`,null,p(_(l)(R.value.recruitedAt?`agentProfiles.joined`:`agentProfiles.created`))+` · `+p(Q(R.value.recruitedAt||R.value.createdAt)),1)])]),c(`div`,Ce,[Z.value?(n(),y(_(D),{key:0,class:`quiet-button`,to:`/employees/${encodeURIComponent(Z.value.id)}`},{default:e(()=>[a(p(_(l)(`agentProfiles.workbench`)),1)]),_:1},8,[`to`])):x(``,!0),c(`button`,{class:`quiet-button`,type:`button`,"aria-expanded":K.value,onClick:s[1]||=e=>K.value=!K.value},p(_(l)(`agentProfiles.settings`)),9,we),t(_(D),{class:`quiet-button`,to:{path:`/employees/bole`,query:{q:_(N)(R.value)}}},{default:e(()=>[a(p(_(l)(`agentProfiles.askHR`)),1)]),_:1},8,[`to`])])]),_(I)||_(b).runtimeStatus===`loading`?(n(),y(T,{key:0,variant:`compact`,label:_(l)(`agentProfiles.loading`)},null,8,[`label`])):x(``,!0),_(L)?(n(),u(`p`,Te,p(_(L)),1)):x(``,!0),K.value?(n(),y(me,{key:R.value.agentId,agent:R.value,onSaved:Ft},null,8,[`agent`])):x(``,!0),W.value?(n(),y(T,{key:3,variant:`compact`,label:_(l)(`agentProfiles.detailLoading`)},null,8,[`label`])):x(``,!0),c(`nav`,{class:`agent-profile-tabs`,role:`tablist`,"aria-label":_(l)(`agentProfiles.profile`)},[(n(!0),u(h,null,r(J.value,e=>(n(),u(`button`,{id:`agent-tab-${e.id}`,key:e.id,class:`agent-profile-tab`,type:`button`,role:`tab`,"aria-selected":q.value===e.id,"aria-controls":`agent-panel-${e.id}`,tabindex:q.value===e.id?0:-1,onClick:t=>It(e.id),onKeydown:t=>Lt(t,J.value.findIndex(t=>t.id===e.id))},p(e.label),41,De))),128))],8,Ee),G.value?(n(),u(`p`,Oe,p(_(l)(`agentProfiles.partial`)),1)):x(``,!0),o(c(`section`,{id:`agent-panel-overview`,class:`agent-profile-panel`,role:`tabpanel`,"aria-labelledby":`agent-tab-overview`,"aria-hidden":q.value!==`overview`,tabindex:`0`},[c(`div`,Ae,[c(`section`,je,[c(`div`,Me,[c(`h2`,null,p(_(l)(`agentProfiles.working`)),1),X.value.length?(n(),u(`span`,Ne,p(X.value.length),1)):x(``,!0)]),X.value.length?(n(),u(`ul`,Pe,[(n(!0),u(h,null,r(X.value,r=>(n(),u(`li`,{key:r.taskId},[t(_(D),{to:{path:`/project-agents/manage`,query:{agent:R.value.agentId,task:r.taskId}}},{default:e(()=>[a(p(r.title),1)]),_:2},1032,[`to`]),c(`span`,Fe,p(_(l)(`projectAgents.taskStatus.${r.status}`)),1)]))),128))])):!W.value&&!G.value?(n(),u(`p`,Ie,p(_(l)(`agentProfiles.idle`)),1)):W.value?x(``,!0):(n(),u(`p`,Le,p(_(l)(`agentProfiles.partial`)),1))]),c(`section`,Re,[c(`div`,ze,[c(`h2`,null,p(_(l)(`agentProfiles.projects`)),1),c(`span`,null,p(Y.value.length),1)]),c(`ul`,Be,[(n(!0),u(h,null,r(At.value,r=>(n(),u(`li`,{key:r,class:`agent-project-item`},[c(`h3`,null,[t(_(D),{class:`agent-project-link`,to:_(A)(C.value,`graph`,r)},{default:e(()=>[a(p(z(r)),1)]),_:2},1032,[`to`])]),$(r)?(n(),u(`p`,Ve,p($(r)),1)):x(``,!0)]))),128))]),jt.value.length?(n(),y(k,{key:0,class:`agent-project-overflow`,title:Nt.value},{default:e(()=>[c(`ul`,He,[(n(!0),u(h,null,r(jt.value,r=>(n(),u(`li`,{key:r,class:`agent-project-item`},[c(`h3`,null,[t(_(D),{class:`agent-project-link`,to:_(A)(C.value,`graph`,r)},{default:e(()=>[a(p(z(r)),1)]),_:2},1032,[`to`])]),$(r)?(n(),u(`p`,Ue,p($(r)),1)):x(``,!0)]))),128))])]),_:1},8,[`title`])):x(``,!0),!W.value&&!Y.value.length?(n(),u(`p`,We,p(_(l)(`agentProfiles.noProject`)),1)):x(``,!0)])])],8,ke),[[d,q.value===`overview`]]),o(c(`section`,{id:`agent-panel-history`,class:`agent-profile-panel`,role:`tabpanel`,"aria-labelledby":`agent-tab-history`,"aria-hidden":q.value!==`history`,tabindex:`0`},[c(`section`,Ke,[c(`h2`,null,p(_(l)(`agentProfiles.projects`)),1),Mt.value.length?(n(),u(`details`,qe,[c(`summary`,null,p(_(l)(`agentProfiles.projectHistory`)),1),c(`ul`,Je,[(n(!0),u(h,null,r(Mt.value,r=>(n(),u(`li`,{key:r.assignmentId},[c(`h3`,null,[t(_(D),{class:`agent-project-link`,to:_(A)(C.value,`graph`,r.personalProjectId)},{default:e(()=>[a(p(z(r.personalProjectId)),1)]),_:2},1032,[`to`])]),c(`p`,null,p(r.responsibility),1),c(`small`,null,p(Q(r.assignedAt))+` – `+p(Q(r.endedAt)),1)]))),128))])])):W.value?x(``,!0):(n(),u(`p`,Ye,p(_(l)(`agentProfiles.noProject`)),1))]),c(`section`,Xe,[c(`h2`,null,p(_(l)(`agentProfiles.experience`)),1),c(`p`,Ze,p(_(l)(`agentProfiles.recent`)),1),c(`ol`,Qe,[(n(!0),u(h,null,r(V.value.slice(0,12),r=>(n(),u(`li`,{key:r.taskId},[c(`div`,$e,[t(_(D),{to:{path:`/project-agents/manage`,query:{agent:R.value.agentId,task:r.taskId}}},{default:e(()=>[a(p(r.title),1)]),_:2},1032,[`to`]),c(`span`,null,p(_(l)(`projectAgents.taskStatus.${r.status}`)),1)]),r.resultSummary?(n(),u(`p`,et,p(r.resultSummary),1)):x(``,!0),c(`small`,null,p(Q(r.completedAt||r.updatedAt||r.createdAt)),1)]))),128)),R.value.recruitedAt||R.value.recruitmentReason?(n(),u(`li`,tt,[c(`h3`,null,p(_(l)(`agentProfiles.recruitment`)),1),R.value.recruitmentReason?(n(),u(`p`,nt,p(R.value.recruitmentReason),1)):x(``,!0),c(`small`,null,p(Q(R.value.recruitedAt)),1)])):x(``,!0)]),!W.value&&!V.value.length&&!R.value.recruitmentReason&&!R.value.recruitedAt?(n(),u(`p`,rt,p(_(l)(`agentProfiles.noExperience`)),1)):x(``,!0)])],8,Ge),[[d,q.value===`history`]]),o(c(`section`,{id:`agent-panel-style`,class:`agent-profile-panel`,role:`tabpanel`,"aria-labelledby":`agent-tab-style`,"aria-hidden":q.value!==`style`,tabindex:`0`},[c(`section`,at,[c(`h2`,null,p(_(l)(`agentProfiles.about`)),1),c(`div`,ot,[(n(),u(h,null,r([`judgment`,`taste`,`personality`],e=>c(`div`,{key:e},[c(`h3`,null,p(_(l)(`agentProfiles.${e}`)),1),c(`p`,{class:g({"agent-muted":!R.value.profile.character?.[e]})},p(R.value.profile.character?.[e]||_(l)(`agentProfiles.characterEmpty`)),3)])),64))]),R.value.profile.expectations?(n(),u(`p`,st,[c(`strong`,null,p(_(l)(`agentProfiles.expectations`)),1),a(` `+p(R.value.profile.expectations),1)])):x(``,!0),c(`div`,ct,[c(`h3`,null,p(_(l)(`agentProfiles.strengths`)),1),c(`div`,lt,[(n(!0),u(h,null,r(R.value.profile.capabilities,e=>(n(),u(`span`,{key:e},p(e),1))),128)),R.value.profile.capabilities.length?x(``,!0):(n(),u(`span`,ut,p(_(l)(`agentProfiles.noSkills`)),1))])])])],8,it),[[d,q.value===`style`]]),o(c(`section`,{id:`agent-panel-collaborators`,class:`agent-profile-panel`,role:`tabpanel`,"aria-labelledby":`agent-tab-collaborators`,"aria-hidden":q.value!==`collaborators`,tabindex:`0`},[c(`section`,ft,[c(`div`,pt,[c(`h2`,null,p(_(l)(`agentProfiles.organization`)),1),t(_(D),{to:{path:`/employees/bole`,query:{q:_(N)(R.value)}}},{default:e(()=>[a(p(_(l)(`agentProfiles.hr`)),1)]),_:1},8,[`to`])]),(n(!0),u(h,null,r(U.value,e=>(n(),u(`div`,{key:e.projectId,class:`agent-organization`},[c(`h3`,null,p(z(e.projectId)),1),e.error?(n(),u(`p`,mt,p(_(l)(`agentProfiles.teamUnavailable`)),1)):e.policy?.teamLeadAgentId||e.policy?.teamMemberAgentIds?.length?(n(),u(h,{key:1},[e.policy.teamLeadAgentId?(n(),u(`div`,ht,[c(`span`,null,p(_(l)(`agentProfiles.lead`)),1),t(P,{"space-id":C.value,"agent-id":e.policy.teamLeadAgentId,name:B(e.policy.teamLeadAgentId)},null,8,[`space-id`,`agent-id`,`name`])])):x(``,!0),e.policy.teamMemberAgentIds?.length?(n(),u(`div`,gt,[c(`span`,null,p(_(l)(`agentProfiles.teammates`)),1),c(`ul`,null,[(n(!0),u(h,null,r([...new Set(e.policy.teamMemberAgentIds)].filter(t=>t!==e.policy?.teamLeadAgentId),e=>(n(),u(`li`,{key:e},[t(P,{"space-id":C.value,"agent-id":e,name:B(e)},null,8,[`space-id`,`agent-id`,`name`])]))),128))])])):x(``,!0)],64)):(n(),u(`p`,_t,p(_(l)(`agentProfiles.teamUnset`)),1))]))),128)),!W.value&&!U.value.length?(n(),u(`p`,vt,p(_(l)(`agentProfiles.noProject`)),1)):x(``,!0)]),c(`section`,yt,[c(`h2`,null,p(_(l)(`agentProfiles.collaborators`)),1),c(`ul`,bt,[(n(!0),u(h,null,r(kt.value,e=>(n(),u(`li`,{key:e.agentId},[t(P,{"space-id":C.value,"agent-id":e.agentId,name:B(e.agentId)},null,8,[`space-id`,`agent-id`,`name`]),c(`span`,null,p(_(l)(`agentProfiles.sharedTasks`,{count:e.count})),1)]))),128))]),!W.value&&!kt.value.length?(n(),u(`p`,xt,p(_(l)(`agentProfiles.noCollaborators`)),1)):x(``,!0)])],8,dt),[[d,q.value===`collaborators`]]),R.value.memoryScope===`reviewed_agent`?o((n(),u(`section`,{key:5,id:`agent-panel-conversations`,class:`agent-profile-panel`,role:`tabpanel`,"aria-labelledby":`agent-tab-conversations`,"aria-hidden":q.value!==`conversations`,tabindex:`0`},[c(`section`,Ct,[(n(),y(ne,{key:R.value.agentId,"personal-space-id":C.value,"agent-id":R.value.agentId,projects:pe.value},null,8,[`personal-space-id`,`agent-id`,`projects`]))])],8,St)),[[d,q.value===`conversations`]]):x(``,!0),o(c(`section`,{id:`agent-panel-management`,class:`agent-profile-panel`,role:`tabpanel`,"aria-labelledby":`agent-tab-management`,"aria-hidden":q.value!==`management`,tabindex:`0`},[c(`section`,Tt,[c(`h2`,null,p(_(l)(`agentProfiles.advanced`)),1),c(`p`,Et,p(_(l)(`agentProfiles.locked`)),1),c(`div`,Dt,[Z.value?(n(),y(_(D),{key:0,class:`quiet-button`,to:`/employees/${encodeURIComponent(Z.value.id)}`},{default:e(()=>[a(p(_(l)(`agentProfiles.workbench`)),1)]),_:1},8,[`to`])):x(``,!0),t(_(D),{class:`quiet-button`,to:{path:`/project-agents/manage`,query:{agent:R.value.agentId}}},{default:e(()=>[a(p(_(l)(`agentProfiles.advanced`)),1)]),_:1},8,[`to`])])])],8,wt),[[d,q.value===`management`]]),c(`footer`,Ot,[Z.value?(n(),y(_(D),{key:0,to:`/employees/${encodeURIComponent(Z.value.id)}`},{default:e(()=>[a(p(_(l)(`agentProfiles.workbench`)),1)]),_:1},8,[`to`])):x(``,!0),t(_(D),{to:{path:`/project-agents/manage`,query:{agent:R.value.agentId}}},{default:e(()=>[a(p(_(l)(`agentProfiles.advanced`)),1)]),_:1},8,[`to`])])],64)):(n(),u(`p`,_e,p(_(l)(`agentProfiles.unavailable`)),1))],8,he))}});export{B as default};
@@ -1 +0,0 @@
1
- import{B as e,C as t,M as n,P as r,R as i,S as a,V as o,X as s,_ as c,a as l,b as u,d,g as f,it as p,j as m,m as h,nt as g,tt as _,u as v,v as y,w as b,y as x}from"./i18n-CCMR4gDS.js";import{t as S}from"./console-CG8tdtSs.js";import{n as C,o as w}from"./client-CUTkF3t4.js";import{t as T}from"./_plugin-vue_export-helper-BDNMzG2s.js";import{h as E,m as D}from"./useApi-CROJJdhE-DlOiu8lP.js";import{t as O}from"./vue-router-DjqEU4W2.js";import{t as k}from"./UiSelect-D5Xj5Ec4.js";import{t as A}from"./AgentHand-BBM-sKh2.js";import{a as j,i as ee,n as M,t as N}from"./profile-model-BQO4zNs9.js";import{n as P,t as F}from"./agent-work-summary-LeW-Al_S.js";import{t as te}from"./useAgentRoster-DdxoKDEE.js";import{a as I,s as L}from"./catalog-6SN9i3WR.js";/* empty css */import{t as ne}from"./ProjectAgentFirstTask-CrCWEYgn.js";import{n as R,t as re}from"./EmployeeRecruitDialog-BVyclQAJ.js";var z={class:`ui-card agent-card`},B={class:`agent-card-topline`},V={class:`agent-portrait small`,"aria-hidden":`true`},H={class:`agent-directory-name`},U={key:0,class:`ui-badge ui-badge--accent agent-card-role`},W=[`data-membership-status`],G=[`data-work-status`,`aria-label`],K={class:`agent-card-responsibility`},q={key:0,class:`agent-inline-skills`},J={class:`agent-card-meta`},Y={class:`agent-card-projects`},X={key:0,class:`agent-card-project-list`},Z={key:0,class:`ui-badge agent-card-project-count`},Q={key:1,class:`ui-badge`},$={key:2,class:`agent-card-no-project`},ie=b({__name:`AgentCard`,props:{agent:{},spaceId:{},projectNames:{},managesAllProjects:{type:Boolean},workSummary:{},workState:{}},setup(i){let o=i,s=f(()=>N(o.agent)),d=f(()=>j(o.agent)),m=f(()=>d.value.slice(0,2).map(e=>o.projectNames?.[e]||e)),v=f(()=>Math.max(d.value.length-2,0)),y=f(()=>o.agent.profile.capabilities.slice(0,3)),b=f(()=>`is-${o.agent.profile.status}`),S=f(()=>l(`projectAgents.status.${o.agent.profile.status}`)),C=f(()=>o.workSummary?o.workSummary.status:o.workState===`loading`?`loading`:o.workState===`error`?`unavailable`:o.workState===`incomplete`?`unreported`:`none`),w=f(()=>`is-${C.value}`),T=f(()=>({coordinator:l(`agentProfiles.roles.projectManager`),hr:l(`agentProfiles.roles.hr`)})[o.agent.profile.agentType]??``);function E(e,t,n){let r=l(e,n);return r===e?t:r}let D=f(()=>E(`agentRedesign.membershipStatus`,`Member · ${S.value}`,{status:S.value})),k=f(()=>{let e={awaiting_recruitment:`Awaiting recruitment`,queued:`Queued`,running:`Running`,paused:`Paused`,awaiting_review:`Awaiting review`,blocked:`Blocked`,none:l(`agentProfiles.idle`),loading:`Loading work status`,unreported:`Partial status`,unavailable:`Unavailable`}[C.value];return E(`agentRedesign.workStatus.${C.value}`,e??`Work status unavailable`)});return(o,d)=>(n(),u(`article`,z,[c(`div`,B,[c(`span`,V,p(i.agent.profile.occupationEmoji||s.value.slice(0,1)),1),c(`div`,H,[t(_(O),{to:_(M)(i.spaceId,i.agent.agentId),"aria-label":`${s.value} · ${_(l)(`agentProfiles.profile`)}`},{default:e(()=>[a(p(s.value),1)]),_:1},8,[`to`,`aria-label`]),T.value?(n(),u(`span`,U,p(T.value),1)):x(``,!0),t(A,{"agent-id":i.agent.agentId},null,8,[`agent-id`])]),i.agent.profile.status===`active`?x(``,!0):(n(),u(`span`,{key:0,class:g([`ui-badge agent-card-status agent-card-membership-status`,b.value]),"data-membership-status":i.agent.profile.status},p(D.value),11,W)),i.agent.profile.status===`active`||![`none`,`loading`].includes(C.value)?(n(),u(`span`,{key:1,class:g([`agent-card-work-status`,w.value]),"data-work-status":C.value,"aria-label":`${_(l)(`agentRedesign.workStatus.label`)} · ${k.value}`},p(k.value),11,G)):x(``,!0)]),c(`p`,K,p(i.agent.profile.responsibility),1),y.value.length?(n(),u(`div`,q,[(n(!0),u(h,null,r(y.value,e=>(n(),u(`span`,{key:e},p(e),1))),128))])):x(``,!0),c(`div`,J,[c(`div`,Y,[m.value.length?(n(),u(`div`,X,[(n(!0),u(h,null,r(m.value,e=>(n(),u(`span`,{key:e,class:`ui-badge`},p(e),1))),128)),v.value?(n(),u(`span`,Z,` +`+p(v.value),1)):x(``,!0)])):i.managesAllProjects?(n(),u(`span`,Q,p(_(l)(`agentProfiles.allProjects`)),1)):(n(),u(`span`,$,p(_(l)(`agentProfiles.noProject`)),1))]),t(_(O),{class:`agent-directory-open`,to:_(M)(i.spaceId,i.agent.agentId),"aria-label":`${s.value} · ${_(l)(`agentProfiles.profile`)}`},{default:e(()=>[a(p(_(l)(`agentProfiles.profile`))+` → `,1)]),_:1},8,[`to`,`aria-label`])])]))}});function ae(e){let t=s({}),n=s(!1),r=s(``),a=s(`idle`),o=new Map,c=0;async function u(){let i=++c,s=e.value;if(r.value=``,!s){t.value={},n.value=!1,a.value=`idle`;return}let u=o.get(s);u?t.value=u:Object.keys(t.value).length&&(t.value={}),n.value=!0,a.value=`loading`;try{let n=await C(`/api/project-agent-tasks?${new URLSearchParams({personalSpaceId:s,limit:`200`})}`);if(i!==c||e.value!==s)return;let r=P(n,s);o.set(s,r),t.value=r,a.value=F(n)?`ready`:`incomplete`}catch(t){if(i!==c||e.value!==s)return;r.value=t instanceof Error?t.message:l(`agentProfiles.loadError`),a.value=`error`}finally{i===c&&e.value===s&&(n.value=!1)}}return i(e,u,{immediate:!0}),{summaries:t,loading:n,error:r,state:a,load:u}}var oe=[`src`],se=T(b({__name:`EmployeeWorkbenchLinks`,props:{personalSpaceId:{}},setup(t){let o=t;i(()=>o.personalSpaceId,e=>{L(e===`current`?``:e)},{immediate:!0});let s=f(()=>I.value.filter(e=>e.agentId&&e.agentStatus===`active`&&(e.runtime||e.workbench?.kind===`native`)));return(t,i)=>(n(!0),u(h,null,r(s.value,t=>(n(),y(_(O),{key:t.id,class:`ui-button employee-workbench-link`,to:`/employees/${encodeURIComponent(t.id)}`,title:_(l)(`agentProfiles.workbench`)},{default:e(()=>[_(R)(t.id)?(n(),u(`img`,{key:0,src:_(R)(t.id),alt:``,"aria-hidden":`true`},null,8,oe)):x(``,!0),a(` `+p(t.name)+` · `+p(t.role),1)]),_:2},1032,[`to`,`title`]))),128))}}),[[`__scopeId`,`data-v-4906fde1`]]),ce=[`aria-label`],le={class:`ui-toolbar agents-directory-heading`},ue={key:0,class:`agents-directory-count`},de={key:1,class:`agents-directory-count`,"aria-hidden":`true`},fe={class:`agent-profile-actions`},pe=[`disabled`],me={key:1,class:`agent-directory-work-error`,role:`status`},he={class:`ui-toolbar agents-directory-filters`},ge={class:`agents-directory-search`},_e={class:`sr-only`},ve=[`placeholder`],ye={key:3,role:`alert`,class:`ui-card ui-empty agent-profile-empty`},be={key:4,class:`ui-card ui-empty agent-profile-empty`},xe={key:5,class:`agents-directory-grid`},Se=b({__name:`AgentsDirectoryPage`,setup(e){let a=S(),g=D(),b=E(),C=f(()=>a.activePersonalSpace?.id??``),{agents:T,loading:O,error:A,load:P}=te(C),{summaries:F,loading:L,error:R,state:z,load:B}=ae(C),V=s(typeof g.query.q==`string`?g.query.q:``),H=s(`all`),U=s(typeof g.query.project==`string`?[g.query.project]:[]),W=s(!1),G=f(()=>I.value.some(e=>!e.fixed)),K=e=>I.value.some(t=>t.agentId===e&&t.management?.mode===`all`),q=f(()=>(a.state?.personalProjects??[]).filter(e=>e.personal_space_id===C.value)),J=f(()=>q.value.map(e=>({value:e.project_id,label:e.profile.name}))),Y=f(()=>Object.fromEntries(J.value.map(e=>[e.value,e.label]))),X=f(()=>[{value:`all`,label:l(`agentProfiles.allStatus`)},...[`active`,`inactive`,`archived`].map(e=>({value:e,label:l(`projectAgents.status.${e}`)}))]),Z=f(()=>T.value.filter(e=>(H.value===`all`||e.profile.status===H.value)&&(!U.value.length||j(e).some(e=>U.value.includes(e)))&&ee([N(e),e.profile.responsibility,...e.profile.capabilities,...j(e).map(e=>Y.value[e]||e)].join(` `),V.value)).sort((e,t)=>N(e).localeCompare(N(t)))),Q=f(()=>O.value||L.value||a.runtimeStatus===`loading`),$=e=>F.value[e];m(()=>{a.runtimeStatus===`idle`&&a.refresh()}),i([C,()=>g.query.agent],([e,t])=>{if(e&&typeof t==`string`){let{agent:n,...r}=g.query;b.replace({path:typeof g.query.task==`string`?`/project-agents/manage`:M(e,t),query:typeof g.query.task==`string`?g.query:r})}},{immediate:!0}),i(C,(e,t)=>{t&&(V.value=``,U.value=[],H.value=`all`)});async function oe(e){W.value=!1,await b.push(M(C.value,e.agent.agentId))}async function Se(){if(a.state){await Promise.allSettled([P(),B()]);return}await a.refresh(),await Promise.allSettled([P(),B()])}return(e,i)=>(n(),u(`section`,{class:`view agents-directory`,"aria-label":_(l)(`agentProfiles.title`)},[c(`header`,le,[!Q.value||_(T).length?(n(),u(`p`,ue,p(_(l)(`agentProfiles.members`,{count:_(T).length})),1)):(n(),u(`span`,de,`\xA0`)),c(`div`,fe,[Q.value&&_(T).length?(n(),y(w,{key:0,variant:`inline`,label:_(l)(`agentRedesign.refreshing`)},null,8,[`label`])):x(``,!0),t(se,{"personal-space-id":C.value||`current`},null,8,[`personal-space-id`]),G.value?(n(),u(`button`,{key:1,type:`button`,class:`primary-button`,disabled:!C.value,onClick:i[0]||=e=>W.value=!0},p(_(l)(`employees.recruit`)),9,pe)):x(``,!0)])]),!Q.value&&!_(A)&&_(a).runtimeStatus===`ready`&&!q.value.length?(n(),y(ne,{key:0,"personal-space-id":C.value},null,8,[`personal-space-id`])):x(``,!0),_(R)?(n(),u(`p`,me,[c(`span`,null,p(_(l)(`agentRedesign.workStatus.refreshError`)),1),c(`button`,{class:`quiet-button`,type:`button`,onClick:i[1]||=(...e)=>_(B)&&_(B)(...e)},p(_(l)(`agentProfiles.retry`)),1)])):x(``,!0),c(`div`,he,[c(`label`,ge,[c(`span`,_e,p(_(l)(`agentProfiles.search`)),1),o(c(`input`,{"onUpdate:modelValue":i[2]||=e=>V.value=e,type:`search`,maxlength:`160`,placeholder:_(l)(`agentProfiles.search`)},null,8,ve),[[v,V.value]])]),t(k,{modelValue:U.value,"onUpdate:modelValue":i[3]||=e=>U.value=e,class:`agents-directory-select`,multiple:``,options:J.value,label:_(l)(`employees.filterLabel`),placeholder:_(l)(`employees.allProjectsFilter`)},null,8,[`modelValue`,`options`,`label`,`placeholder`]),t(k,{modelValue:H.value,"onUpdate:modelValue":i[4]||=e=>H.value=e,class:`agents-directory-select`,options:X.value,label:_(l)(`projectAgents.fields.status`)},null,8,[`modelValue`,`options`,`label`])]),Q.value&&!_(T).length?(n(),y(w,{key:2,label:_(l)(`agentProfiles.loading`)},null,8,[`label`])):x(``,!0),_(A)||_(a).runtimeStatus===`error`?o((n(),u(`div`,ye,[c(`p`,null,p(_(A)||_(l)(`agentProfiles.loadError`)),1),c(`button`,{class:`quiet-button`,type:`button`,onClick:Se},p(_(l)(`agentProfiles.retry`)),1)],512)),[[d,!Q.value||_(T).length===0]]):x(``,!0),!Q.value&&!Z.value.length&&!_(A)&&_(a).runtimeStatus!==`error`?(n(),u(`p`,be,p(_(l)(_(T).length?`agentProfiles.noMatch`:`agentProfiles.noAgents`)),1)):x(``,!0),Z.value.length?(n(),u(`ul`,xe,[(n(!0),u(h,null,r(Z.value,e=>(n(),u(`li`,{key:e.agentId},[t(ie,{agent:e,"space-id":C.value,"project-names":Y.value,"manages-all-projects":K(e.agentId),"work-summary":$(e.agentId),"work-state":_(z)},null,8,[`agent`,`space-id`,`project-names`,`manages-all-projects`,`work-summary`,`work-state`])]))),128))])):x(``,!0),t(re,{open:W.value,"personal-space-id":C.value,projects:q.value,"default-project-ids":U.value??[],onClose:i[5]||=e=>W.value=!1,onRecruited:oe},null,8,[`open`,`personal-space-id`,`projects`,`default-project-ids`])],8,ce))}});export{Se as default};
@@ -1 +0,0 @@
1
- import{M as e,v as t,w as n}from"./i18n-CCMR4gDS.js";import{t as r}from"./KnowledgeWorkspace-BtRq9fvC.js";var i=n({__name:`KnowledgePage`,setup(n){return(n,i)=>(e(),t(r))}});export{i as default};
@@ -1 +0,0 @@
1
- import{M as e,v as t,w as n}from"./i18n-CCMR4gDS.js";import{t as r}from"./KnowledgeWorkspace-BtRq9fvC.js";var i=n({__name:`PersonalProjectsPage`,setup(n){return(n,i)=>(e(),t(r,{"personal-projects-only":``}))}});export{i as default};