fuli-context 0.7.5 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/web/assets/{AboutPage-ByCUor-j.js → AboutPage-sLV9WChi.js} +1 -1
- package/dist/web/assets/{ConnectionsPage-DkdkZ40Q.js → ConnectionsPage-BWn4ywGJ.js} +1 -1
- package/dist/web/assets/{KnowledgeEditDialog-DSe3Gwep.js → KnowledgeEditDialog-CZ5ziPrD.js} +1 -1
- package/dist/web/assets/{KnowledgeInspector-CYAjAb9J.js → KnowledgeInspector-CRQWOaos.js} +1 -1
- package/dist/web/assets/{KnowledgeOrganizerPage-CV4F54R_.js → KnowledgeOrganizerPage-Dfj3vIpU.js} +1 -1
- package/dist/web/assets/KnowledgePage-BRYC9S5Y.js +1 -0
- package/dist/web/assets/{KnowledgeWorkspace-z4u5mXOG.js → KnowledgeWorkspace-ChEB5Bwk.js} +1 -1
- package/dist/web/assets/{OverviewPage-BWOfeS6k.js → OverviewPage-Cd66M0RT.js} +1 -1
- package/dist/web/assets/{PersonalProfilePage-c3w4-h7a.js → PersonalProfilePage-RCFHL0Wz.js} +1 -1
- package/dist/web/assets/PersonalProjectsPage-DEh8XWby.js +1 -0
- package/dist/web/assets/ProjectAgentsPage-Crh7PrXa.css +1 -0
- package/dist/web/assets/ProjectAgentsPage-DPnaH-TR.js +11 -0
- package/dist/web/assets/{PublicProjectsPage-DdH0oGB3.js → PublicProjectsPage-mstPEjHe.js} +1 -1
- package/dist/web/assets/{ReviewPage-BYIpcIHG.js → ReviewPage-6Y1SmfZy.js} +1 -1
- package/dist/web/assets/{SearchableSelect-Dz13ClQb.js → SearchableSelect-D3HM8YF8.js} +1 -1
- package/dist/web/assets/{SettingsPage-2VkbXgZi.js → SettingsPage--LdTMUm7.js} +1 -1
- package/dist/web/assets/{WritingTastePage-BOPQZuva.js → WritingTastePage-CIpKswvs.js} +1 -1
- package/dist/web/assets/{console-BlAhujsH.js → console-BT1P2Db4.js} +1 -1
- package/dist/web/assets/{conversation-launcher-settings-DTYxiLJt.js → conversation-launcher-settings-DrJEotdf.js} +1 -1
- package/dist/web/assets/{i18n-Ci3heuiL.js → i18n-js6gfc7j.js} +2 -2
- package/dist/web/assets/{identity-4_-v6cB7.js → identity-CfDfanpa.js} +1 -1
- package/dist/web/assets/{index-C67Q0JY2.js → index-GqJf1xqg.js} +2 -2
- package/dist/web/assets/{model-yG0YqUyZ.js → model-DJkLAJsg.js} +1 -1
- package/dist/web/assets/{useApi-CROJJdhE-twhdZArA.js → useApi-CROJJdhE-BdSti7Y2.js} +1 -1
- package/dist/web/assets/{vue-router-C-wot_Di.js → vue-router-Kk67EaCP.js} +1 -1
- package/dist/web/index.html +5 -5
- package/graph-provider/fuli_graph/project_agent_coordination_models.py +22 -0
- package/graph-provider/fuli_graph/project_agent_routes.py +29 -0
- package/graph-provider/fuli_graph/project_agent_task_models.py +3 -0
- package/graph-provider/fuli_graph/store_project_agent_coordination_policy.py +122 -0
- package/graph-provider/fuli_graph/store_project_agent_task_recruitment.py +9 -3
- package/graph-provider/fuli_graph/store_project_agent_task_staffing.py +177 -0
- package/graph-provider/fuli_graph/store_project_agent_tasks.py +7 -0
- package/graph-provider/pyproject.toml +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/src/agent-tools/graph-definitions.js +23 -0
- package/src/agent-tools/graph-handlers.js +4 -0
- package/src/graphiti/project-agent-control-plane.js +12 -0
- package/src/graphiti/project-agent-mapping.js +21 -0
- package/src/graphiti/project-agent-workflows.js +19 -0
- package/src/graphiti/provider-client.js +12 -0
- package/src/http/graph-api-router.js +12 -0
- package/src/mcp/tool-annotations.js +2 -0
- package/dist/web/assets/KnowledgePage-vYYXipOi.js +0 -1
- package/dist/web/assets/PersonalProjectsPage-B7AlLEwf.js +0 -1
- package/dist/web/assets/ProjectAgentsPage-CgftpIPB.css +0 -1
- package/dist/web/assets/ProjectAgentsPage-DTHcL_ox.js +0 -11
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Agent assignment selection, history continuity, and parallel staffing."""
|
|
2
2
|
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
3
5
|
from fastapi import HTTPException
|
|
4
6
|
|
|
5
7
|
from .project_agent_access import authorize_project_agent
|
|
@@ -50,6 +52,26 @@ class StoreProjectAgentTaskStaffing:
|
|
|
50
52
|
else 'explicit_new_agent',
|
|
51
53
|
['user explicitly requested recruitment'],
|
|
52
54
|
)
|
|
55
|
+
policy = await self.get_project_agent_coordination_policy(
|
|
56
|
+
actor,
|
|
57
|
+
request.personal_space_id,
|
|
58
|
+
request.personal_project_id,
|
|
59
|
+
)
|
|
60
|
+
if not policy.auto_reuse_previous_agent:
|
|
61
|
+
return [], rows, 'manual_agent_selection', [
|
|
62
|
+
'project policy requires an explicit @Agent selection',
|
|
63
|
+
]
|
|
64
|
+
continuity, project_history = await self._rank_project_continuity(
|
|
65
|
+
rows,
|
|
66
|
+
request,
|
|
67
|
+
)
|
|
68
|
+
if continuity:
|
|
69
|
+
selected = continuity[0]
|
|
70
|
+
return [selected], continuity, 'project_continuity', [
|
|
71
|
+
self._project_history_match_basis(
|
|
72
|
+
project_history.get(selected['agent_id']),
|
|
73
|
+
),
|
|
74
|
+
]
|
|
53
75
|
normalized_work_kind = request.work_kind.casefold()
|
|
54
76
|
required = {item.casefold() for item in request.required_capabilities}
|
|
55
77
|
candidates, history = await self._rank_agent_candidates(rows, request)
|
|
@@ -75,6 +97,10 @@ class StoreProjectAgentTaskStaffing:
|
|
|
75
97
|
'matching Agent is unavailable to source client: '
|
|
76
98
|
f'{request.source_application or "other"}',
|
|
77
99
|
]
|
|
100
|
+
if len(rows) == 1:
|
|
101
|
+
return [rows[0]], rows, 'sole_active_assignment', [
|
|
102
|
+
'the project has one active Agent assignment',
|
|
103
|
+
]
|
|
78
104
|
return [], rows, 'no_match', ['no active assignment matched exactly']
|
|
79
105
|
selected = candidates[0]
|
|
80
106
|
if normalized_work_kind in {
|
|
@@ -128,6 +154,107 @@ class StoreProjectAgentTaskStaffing:
|
|
|
128
154
|
)
|
|
129
155
|
return [item[1] for item in scored], history
|
|
130
156
|
|
|
157
|
+
async def _rank_project_continuity(self, rows, request):
|
|
158
|
+
"""Prefer the last effective project lead before task-type matching."""
|
|
159
|
+
|
|
160
|
+
if not rows:
|
|
161
|
+
return [], {}
|
|
162
|
+
history = await self._historical_project_agent_outcomes(
|
|
163
|
+
request.personal_space_id,
|
|
164
|
+
request.personal_project_id,
|
|
165
|
+
[row['agent_id'] for row in rows],
|
|
166
|
+
)
|
|
167
|
+
candidates = [
|
|
168
|
+
row
|
|
169
|
+
for row in rows
|
|
170
|
+
if self._metric_int(
|
|
171
|
+
(history.get(row['agent_id']) or {}).get('participation_count')
|
|
172
|
+
) > 0
|
|
173
|
+
]
|
|
174
|
+
candidates.sort(
|
|
175
|
+
key=lambda row: (
|
|
176
|
+
*self._project_history_sort_key(history.get(row['agent_id'])),
|
|
177
|
+
row['assigned_at'],
|
|
178
|
+
row['agent_id'],
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
return candidates, history
|
|
182
|
+
|
|
183
|
+
async def _historical_project_agent_outcomes(
|
|
184
|
+
self,
|
|
185
|
+
personal_space_id,
|
|
186
|
+
personal_project_id,
|
|
187
|
+
agent_ids,
|
|
188
|
+
):
|
|
189
|
+
"""Read cross-work-kind lead history for sticky project continuity."""
|
|
190
|
+
|
|
191
|
+
if not agent_ids:
|
|
192
|
+
return {}
|
|
193
|
+
runtime = getattr(self, 'runtime', None)
|
|
194
|
+
driver = getattr(runtime, 'driver', None)
|
|
195
|
+
if driver is None:
|
|
196
|
+
return {}
|
|
197
|
+
records, _, _ = await driver.execute_query(
|
|
198
|
+
'''
|
|
199
|
+
MATCH (space:FuliSpace {id: $personal_space_id, kind: 'personal'})-
|
|
200
|
+
[:HAS_PROJECT_AGENT_TASK]->
|
|
201
|
+
(task:FuliProjectAgentTask {
|
|
202
|
+
personal_space_id: $personal_space_id,
|
|
203
|
+
personal_project_id: $personal_project_id
|
|
204
|
+
})-[participant:HAS_PARTICIPANT]->
|
|
205
|
+
(agent:FuliProjectAgent)
|
|
206
|
+
WHERE agent.agent_id IN $agent_ids
|
|
207
|
+
AND (participant.role = 'lead'
|
|
208
|
+
OR task.lead_agent_id = agent.agent_id)
|
|
209
|
+
OPTIONAL MATCH (task)-[:HAS_TASK_EVENT]->
|
|
210
|
+
(event:FuliProjectAgentTaskEvent)-[:EVENT_AGENT]->(agent)
|
|
211
|
+
RETURN agent.agent_id AS agent_id,
|
|
212
|
+
count(DISTINCT task.task_id) AS participation_count,
|
|
213
|
+
count(DISTINCT CASE
|
|
214
|
+
WHEN participant.status = 'completed'
|
|
215
|
+
OR event.status = 'completed'
|
|
216
|
+
THEN task.task_id END
|
|
217
|
+
) AS completed_count,
|
|
218
|
+
count(DISTINCT CASE
|
|
219
|
+
WHEN participant.status = 'failed'
|
|
220
|
+
OR event.status = 'failed'
|
|
221
|
+
THEN task.task_id END
|
|
222
|
+
) AS failed_count,
|
|
223
|
+
count(DISTINCT CASE
|
|
224
|
+
WHEN participant.status = 'cancelled'
|
|
225
|
+
OR event.status = 'cancelled'
|
|
226
|
+
THEN task.task_id END
|
|
227
|
+
) AS cancelled_count,
|
|
228
|
+
max(task.updated_at) AS last_task_at,
|
|
229
|
+
max(CASE
|
|
230
|
+
WHEN participant.status = 'completed'
|
|
231
|
+
OR event.status = 'completed'
|
|
232
|
+
THEN coalesce(event.created_at, task.updated_at) END
|
|
233
|
+
) AS last_completed_at
|
|
234
|
+
''',
|
|
235
|
+
personal_space_id=personal_space_id,
|
|
236
|
+
personal_project_id=personal_project_id,
|
|
237
|
+
agent_ids=list(agent_ids),
|
|
238
|
+
routing_='r',
|
|
239
|
+
)
|
|
240
|
+
result = {}
|
|
241
|
+
for row in records or []:
|
|
242
|
+
raw = dict(row)
|
|
243
|
+
agent_id = raw.get('agent_id')
|
|
244
|
+
if not agent_id:
|
|
245
|
+
continue
|
|
246
|
+
result[agent_id] = {
|
|
247
|
+
'participation_count': self._metric_int(
|
|
248
|
+
raw.get('participation_count')
|
|
249
|
+
),
|
|
250
|
+
'completed_count': self._metric_int(raw.get('completed_count')),
|
|
251
|
+
'failed_count': self._metric_int(raw.get('failed_count')),
|
|
252
|
+
'cancelled_count': self._metric_int(raw.get('cancelled_count')),
|
|
253
|
+
'last_task_at': raw.get('last_task_at'),
|
|
254
|
+
'last_completed_at': raw.get('last_completed_at'),
|
|
255
|
+
}
|
|
256
|
+
return result
|
|
257
|
+
|
|
131
258
|
async def _historical_agent_outcomes(
|
|
132
259
|
self,
|
|
133
260
|
personal_space_id,
|
|
@@ -227,6 +354,56 @@ class StoreProjectAgentTaskStaffing:
|
|
|
227
354
|
-participation,
|
|
228
355
|
)
|
|
229
356
|
|
|
357
|
+
@classmethod
|
|
358
|
+
def _project_history_sort_key(cls, history):
|
|
359
|
+
history = history or {}
|
|
360
|
+
completed = cls._metric_int(history.get('completed_count'))
|
|
361
|
+
failed = cls._metric_int(history.get('failed_count'))
|
|
362
|
+
cancelled = cls._metric_int(history.get('cancelled_count'))
|
|
363
|
+
participation = cls._metric_int(history.get('participation_count'))
|
|
364
|
+
effective_time = (
|
|
365
|
+
history.get('last_completed_at')
|
|
366
|
+
if completed > 0
|
|
367
|
+
else history.get('last_task_at')
|
|
368
|
+
)
|
|
369
|
+
outcome_score = completed * 3 - failed * 2 - cancelled
|
|
370
|
+
return (
|
|
371
|
+
0 if completed > 0 else 1,
|
|
372
|
+
-cls._history_timestamp(effective_time),
|
|
373
|
+
-outcome_score,
|
|
374
|
+
-participation,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
@staticmethod
|
|
378
|
+
def _history_timestamp(value):
|
|
379
|
+
if value is None:
|
|
380
|
+
return 0.0
|
|
381
|
+
if hasattr(value, 'to_native'):
|
|
382
|
+
value = value.to_native()
|
|
383
|
+
if hasattr(value, 'timestamp'):
|
|
384
|
+
try:
|
|
385
|
+
return float(value.timestamp())
|
|
386
|
+
except (TypeError, ValueError, OSError):
|
|
387
|
+
return 0.0
|
|
388
|
+
try:
|
|
389
|
+
return datetime.fromisoformat(
|
|
390
|
+
str(value).replace('Z', '+00:00')
|
|
391
|
+
).timestamp()
|
|
392
|
+
except (TypeError, ValueError, OSError):
|
|
393
|
+
return 0.0
|
|
394
|
+
|
|
395
|
+
@classmethod
|
|
396
|
+
def _project_history_match_basis(cls, history):
|
|
397
|
+
history = history or {}
|
|
398
|
+
participation = cls._metric_int(history.get('participation_count'))
|
|
399
|
+
completed = cls._metric_int(history.get('completed_count'))
|
|
400
|
+
if completed:
|
|
401
|
+
return (
|
|
402
|
+
'last successful project lead continuity: '
|
|
403
|
+
f'{participation} prior task(s), {completed} completed'
|
|
404
|
+
)
|
|
405
|
+
return f'most recent project lead continuity: {participation} prior task(s)'
|
|
406
|
+
|
|
230
407
|
@classmethod
|
|
231
408
|
def _history_match_basis(cls, history, work_kind):
|
|
232
409
|
if not history:
|
|
@@ -29,12 +29,16 @@ from .store_project_agents import SYSTEM_COORDINATOR_AGENT_ID
|
|
|
29
29
|
from .store_project_agent_task_reads import StoreProjectAgentTaskReads
|
|
30
30
|
from .store_project_agent_task_recruitment import StoreProjectAgentTaskRecruitment
|
|
31
31
|
from .store_project_agent_task_staffing import StoreProjectAgentTaskStaffing
|
|
32
|
+
from .store_project_agent_coordination_policy import (
|
|
33
|
+
StoreProjectAgentCoordinationPolicy,
|
|
34
|
+
)
|
|
32
35
|
|
|
33
36
|
|
|
34
37
|
TERMINAL_TASK_STATUSES = {'completed', 'failed', 'cancelled'}
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
class StoreProjectAgentTasks(
|
|
41
|
+
StoreProjectAgentCoordinationPolicy,
|
|
38
42
|
StoreProjectAgentTaskRecruitment,
|
|
39
43
|
StoreProjectAgentTaskReads,
|
|
40
44
|
# Keep the pre-existing base order ahead of the extracted implementation.
|
|
@@ -170,6 +174,9 @@ class StoreProjectAgentTasks(
|
|
|
170
174
|
reason = 'explicit_unassigned'
|
|
171
175
|
routing_outcome = 'unassigned'
|
|
172
176
|
task_status = 'blocked'
|
|
177
|
+
elif reason == 'manual_agent_selection':
|
|
178
|
+
routing_outcome = 'unassigned'
|
|
179
|
+
task_status = 'blocked'
|
|
173
180
|
elif not lead or request.staffing_intent in {'new_durable', 'temporary'}:
|
|
174
181
|
recruitment, recruited = await self._open_recruitment(
|
|
175
182
|
actor,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fuli-context",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "fuli-context",
|
|
9
|
-
"version": "0.7.
|
|
9
|
+
"version": "0.7.6",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@hono/node-server": "2.0.12",
|
package/package.json
CHANGED
|
@@ -780,6 +780,29 @@ export const GRAPH_TOOL_DEFINITIONS = [
|
|
|
780
780
|
toDate: nullableStringSchema()
|
|
781
781
|
}, ['personalSpaceId', 'agentId'])
|
|
782
782
|
},
|
|
783
|
+
{
|
|
784
|
+
name: 'get_project_agent_coordination_policy',
|
|
785
|
+
title: 'READ · Get project Agent continuity policy',
|
|
786
|
+
description: 'Read the exact project policy for asking before recruitment and automatically reusing the previous effective Agent. Both switches default on.',
|
|
787
|
+
inputSchema: objectSchema({
|
|
788
|
+
personalSpaceId: id,
|
|
789
|
+
personalProjectId: id
|
|
790
|
+
}, ['personalSpaceId', 'personalProjectId'])
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
name: 'update_project_agent_coordination_policy',
|
|
794
|
+
title: 'WRITE · Set project Agent continuity policy',
|
|
795
|
+
description: 'Persist the exact project switches for asking before recruitment and automatically reusing its previous effective Agent. This changes policy only and never starts a worker.',
|
|
796
|
+
inputSchema: objectSchema({
|
|
797
|
+
personalSpaceId: id,
|
|
798
|
+
personalProjectId: id,
|
|
799
|
+
askBeforeRecruitment: booleanSchema(),
|
|
800
|
+
autoReusePreviousAgent: booleanSchema()
|
|
801
|
+
}, [
|
|
802
|
+
'personalSpaceId', 'personalProjectId',
|
|
803
|
+
'askBeforeRecruitment', 'autoReusePreviousAgent'
|
|
804
|
+
])
|
|
805
|
+
},
|
|
783
806
|
{
|
|
784
807
|
name: 'get_project_agent_recruitment_policy',
|
|
785
808
|
title: 'READ · Get recruitment policy',
|
|
@@ -92,6 +92,10 @@ const HANDLERS = Object.freeze({
|
|
|
92
92
|
record_project_agent_task_activity: (app, input) =>
|
|
93
93
|
app.recordProjectAgentTaskActivity(input),
|
|
94
94
|
view_project_agent_activity: (app, input) => app.viewProjectAgentActivity(input),
|
|
95
|
+
get_project_agent_coordination_policy: (app, input) =>
|
|
96
|
+
app.getProjectAgentCoordinationPolicy(input),
|
|
97
|
+
update_project_agent_coordination_policy: (app, input) =>
|
|
98
|
+
app.updateProjectAgentCoordinationPolicy(input),
|
|
95
99
|
get_project_agent_recruitment_policy: (app, input) =>
|
|
96
100
|
app.getProjectAgentRecruitmentPolicy(input),
|
|
97
101
|
update_project_agent_recruitment_policy: (app, input) =>
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
getExecutorRoutingRule as getExecutorRoutingRuleWorkflow,
|
|
14
14
|
getProjectAgent as getProjectAgentWorkflow,
|
|
15
15
|
getProjectAgentContext as getProjectAgentContextWorkflow,
|
|
16
|
+
getProjectAgentCoordinationPolicy as getProjectAgentCoordinationPolicyWorkflow,
|
|
16
17
|
getProjectAgentRecruitmentPolicy as getProjectAgentRecruitmentPolicyWorkflow,
|
|
17
18
|
ignoreProjectAgentRoutingLearning as ignoreProjectAgentRoutingLearningWorkflow,
|
|
18
19
|
listCurrentProjectAgents as listCurrentProjectAgentsWorkflow,
|
|
@@ -32,6 +33,7 @@ import {
|
|
|
32
33
|
resetProjectAgentRoutingLearning as resetProjectAgentRoutingLearningWorkflow,
|
|
33
34
|
submitProjectAgentTask as submitProjectAgentTaskWorkflow,
|
|
34
35
|
updateExecutorRoutingRule as updateExecutorRoutingRuleWorkflow,
|
|
36
|
+
updateProjectAgentCoordinationPolicy as updateProjectAgentCoordinationPolicyWorkflow,
|
|
35
37
|
updateProjectAgentRecruitmentPolicy as updateProjectAgentRecruitmentPolicyWorkflow,
|
|
36
38
|
upsertExecutor as upsertExecutorWorkflow,
|
|
37
39
|
upsertExecutorRoutingRule as upsertExecutorRoutingRuleWorkflow,
|
|
@@ -134,6 +136,16 @@ export class ProjectAgentControlPlaneApplication {
|
|
|
134
136
|
return viewProjectAgentActivityWorkflow(this, input);
|
|
135
137
|
}
|
|
136
138
|
|
|
139
|
+
async getProjectAgentCoordinationPolicy(input) {
|
|
140
|
+
this.#assertSpace(input.personalSpaceId);
|
|
141
|
+
return getProjectAgentCoordinationPolicyWorkflow(this, input);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async updateProjectAgentCoordinationPolicy(input) {
|
|
145
|
+
this.#assertSpace(input.personalSpaceId);
|
|
146
|
+
return updateProjectAgentCoordinationPolicyWorkflow(this, input);
|
|
147
|
+
}
|
|
148
|
+
|
|
137
149
|
async getProjectAgentRecruitmentPolicy(input) {
|
|
138
150
|
this.#assertSpace(input.personalSpaceId);
|
|
139
151
|
return getProjectAgentRecruitmentPolicyWorkflow(this, input);
|
|
@@ -612,6 +612,27 @@ export function projectAgentRecruitmentPolicyRecord(value = {}) {
|
|
|
612
612
|
};
|
|
613
613
|
}
|
|
614
614
|
|
|
615
|
+
export function projectAgentCoordinationPolicyRecord(value = {}) {
|
|
616
|
+
return {
|
|
617
|
+
personalSpaceId: value.personal_space_id,
|
|
618
|
+
personalProjectId: value.personal_project_id,
|
|
619
|
+
askBeforeRecruitment: value.ask_before_recruitment ?? true,
|
|
620
|
+
autoReusePreviousAgent: value.auto_reuse_previous_agent ?? true,
|
|
621
|
+
updatedAt: value.updated_at ?? null
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
export function providerProjectAgentCoordinationPolicy(input) {
|
|
626
|
+
return {
|
|
627
|
+
personal_space_id: input.personalSpaceId ?? input.personal_space_id,
|
|
628
|
+
personal_project_id: input.personalProjectId ?? input.personal_project_id,
|
|
629
|
+
ask_before_recruitment:
|
|
630
|
+
input.askBeforeRecruitment ?? input.ask_before_recruitment ?? true,
|
|
631
|
+
auto_reuse_previous_agent:
|
|
632
|
+
input.autoReusePreviousAgent ?? input.auto_reuse_previous_agent ?? true
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
|
|
615
636
|
export function providerProjectAgentRecruitmentDecision(input) {
|
|
616
637
|
return {
|
|
617
638
|
personal_space_id: input.personalSpaceId ?? input.personal_space_id,
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
executorRoutingRuleRecord,
|
|
5
5
|
projectAgentActivityRecord,
|
|
6
6
|
projectAgentAssignmentRecord,
|
|
7
|
+
projectAgentCoordinationPolicyRecord,
|
|
7
8
|
projectAgentRecruitmentPolicyRecord,
|
|
8
9
|
projectAgentRecruitmentRecord,
|
|
9
10
|
projectAgentTaskRecord,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
providerProjectAgentAssignment,
|
|
21
22
|
providerProjectAgentAssignmentEnd,
|
|
22
23
|
providerProjectAgentAssignmentReplace,
|
|
24
|
+
providerProjectAgentCoordinationPolicy,
|
|
23
25
|
providerProjectAgentRecruitmentDecision,
|
|
24
26
|
providerProjectAgentTaskActivity,
|
|
25
27
|
providerProjectAgentTaskOutcome,
|
|
@@ -272,6 +274,23 @@ export async function viewProjectAgentActivity(application, input) {
|
|
|
272
274
|
return projectAgentActivityRecord(value);
|
|
273
275
|
}
|
|
274
276
|
|
|
277
|
+
export async function getProjectAgentCoordinationPolicy(application, input) {
|
|
278
|
+
return projectAgentCoordinationPolicyRecord(
|
|
279
|
+
await application.personal.getProjectAgentCoordinationPolicy(
|
|
280
|
+
input.personalSpaceId,
|
|
281
|
+
input.personalProjectId
|
|
282
|
+
)
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export async function updateProjectAgentCoordinationPolicy(application, input) {
|
|
287
|
+
return projectAgentCoordinationPolicyRecord(
|
|
288
|
+
await application.personal.updateProjectAgentCoordinationPolicy(
|
|
289
|
+
providerProjectAgentCoordinationPolicy(input)
|
|
290
|
+
)
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
|
|
275
294
|
export async function getProjectAgentRecruitmentPolicy(application, input) {
|
|
276
295
|
return projectAgentRecruitmentPolicyRecord(
|
|
277
296
|
await application.personal.getProjectAgentRecruitmentPolicy(input.personalSpaceId)
|
|
@@ -200,6 +200,18 @@ export class GraphitiProviderClient {
|
|
|
200
200
|
`/v1/project-agents/${encodeURIComponent(agentId)}/activity?${query}`
|
|
201
201
|
);
|
|
202
202
|
}
|
|
203
|
+
getProjectAgentCoordinationPolicy(personalSpaceId, personalProjectId) {
|
|
204
|
+
const query = new URLSearchParams({
|
|
205
|
+
personal_space_id: personalSpaceId,
|
|
206
|
+
personal_project_id: personalProjectId
|
|
207
|
+
});
|
|
208
|
+
return this.#request(`/v1/project-agent-coordination-policy?${query}`);
|
|
209
|
+
}
|
|
210
|
+
updateProjectAgentCoordinationPolicy(input) {
|
|
211
|
+
return this.#request('/v1/project-agent-coordination-policy', {
|
|
212
|
+
method: 'PUT', body: input
|
|
213
|
+
});
|
|
214
|
+
}
|
|
203
215
|
getProjectAgentRecruitmentPolicy(personalSpaceId) {
|
|
204
216
|
const query = new URLSearchParams({ personal_space_id: personalSpaceId });
|
|
205
217
|
return this.#request(`/v1/project-agent-recruitment-policy?${query}`);
|
|
@@ -283,6 +283,18 @@ export async function handleGraphApiRequest({
|
|
|
283
283
|
sendJson(response, 200, await app.recordProjectAgentTaskActivity(await readJson(request)));
|
|
284
284
|
return true;
|
|
285
285
|
}
|
|
286
|
+
if (url.pathname === '/api/project-agent-coordination-policy' && request.method === 'GET') {
|
|
287
|
+
sendJson(response, 200, await app.getProjectAgentCoordinationPolicy({
|
|
288
|
+
personalSpaceId: url.searchParams.get('personalSpaceId'),
|
|
289
|
+
personalProjectId: url.searchParams.get('personalProjectId')
|
|
290
|
+
}));
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
if (url.pathname === '/api/project-agent-coordination-policy' &&
|
|
294
|
+
(request.method === 'PUT' || request.method === 'PATCH')) {
|
|
295
|
+
sendJson(response, 200, await app.updateProjectAgentCoordinationPolicy(await readJson(request)));
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
286
298
|
if (url.pathname === '/api/project-agent-recruitment-policy' && request.method === 'GET') {
|
|
287
299
|
sendJson(response, 200, await app.getProjectAgentRecruitmentPolicy({
|
|
288
300
|
personalSpaceId: url.searchParams.get('personalSpaceId')
|
|
@@ -13,6 +13,7 @@ const READ_TOOLS = new Set([
|
|
|
13
13
|
'get_project_agent_context',
|
|
14
14
|
'view_project_agent_task',
|
|
15
15
|
'view_project_agent_activity',
|
|
16
|
+
'get_project_agent_coordination_policy',
|
|
16
17
|
'get_project_agent_recruitment_policy',
|
|
17
18
|
'list_project_agent_recruitments',
|
|
18
19
|
'list_executors',
|
|
@@ -61,6 +62,7 @@ const WRITE_TOOLS = new Set([
|
|
|
61
62
|
'release_runtime_lease',
|
|
62
63
|
'submit_project_agent_task',
|
|
63
64
|
'record_project_agent_task_activity',
|
|
65
|
+
'update_project_agent_coordination_policy',
|
|
64
66
|
'update_project_agent_recruitment_policy',
|
|
65
67
|
'decide_project_agent_recruitment',
|
|
66
68
|
'upsert_executor',
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as e,_ as t,j as n}from"./i18n-Ci3heuiL.js";import{t as r}from"./KnowledgeWorkspace-z4u5mXOG.js";var i=e({__name:`KnowledgePage`,setup(e){return(e,i)=>(n(),t(r))}});export{i as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as e,_ as t,j as n}from"./i18n-Ci3heuiL.js";import{t as r}from"./KnowledgeWorkspace-z4u5mXOG.js";var i=e({__name:`PersonalProjectsPage`,setup(e){return(e,i)=>(n(),t(r,{"personal-projects-only":``}))}});export{i as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.project-agent-assignment-dialog[data-v-27954ba8]{background:0 0;border:0;border-radius:12px;width:min(620px,100vw - 32px);max-height:calc(100vh - 32px);padding:0}.project-agent-assignment-dialog-shell[data-v-27954ba8]{background:#fbfcfb;border:1px solid #d5dcd7;border-radius:12px;flex-direction:column;max-height:calc(100vh - 32px);display:flex;overflow:hidden;box-shadow:0 18px 48px #212d262e}.project-agent-assignment-dialog-header[data-v-27954ba8],.project-agent-assignment-dialog-actions[data-v-27954ba8]{justify-content:space-between;align-items:center;gap:16px;padding:16px 18px;display:flex}.project-agent-assignment-dialog-header[data-v-27954ba8]{border-bottom:1px solid #e1e6e2}.project-agent-assignment-dialog-header h3[data-v-27954ba8]{color:#283a31;font-size:16px}.project-agent-assignment-dialog-fields[data-v-27954ba8]{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;min-height:0;padding:18px;display:grid;overflow:auto}.project-agent-assignment-dialog-fields label[data-v-27954ba8]{color:#626d66;gap:6px;font-size:11px;font-weight:650;display:grid}.project-agent-assignment-dialog-fields input[data-v-27954ba8],.project-agent-assignment-dialog-fields textarea[data-v-27954ba8]{color:#28342d;background:#fff;border:1px solid #ccd5ce;border-radius:8px;width:100%;padding:8px 9px;font-size:12px;line-height:1.5}.project-agent-assignment-dialog-fields textarea[data-v-27954ba8]{resize:vertical}.project-agent-assignment-dialog-fields input[data-v-27954ba8]:focus-visible,.project-agent-assignment-dialog-fields textarea[data-v-27954ba8]:focus-visible{outline-offset:1px;outline:2px solid #91a398}.project-agent-assignment-wide-field[data-v-27954ba8]{grid-column:1/-1}.project-agent-assignment-dialog-error[data-v-27954ba8]{color:#8b3f38;margin:0 18px;font-size:11px}.project-agent-assignment-dialog-actions[data-v-27954ba8]{border-top:1px solid #e1e6e2;justify-content:flex-end}.project-agent-primary-action[data-v-27954ba8]{color:#fff;background:#344c3d;border:0;border-radius:8px;padding:8px 13px;font-size:11px;font-weight:700}.project-agent-primary-action[data-v-27954ba8]:focus-visible{outline-offset:2px;outline:2px solid #91a398}@media (width<=620px){.project-agent-assignment-dialog-fields[data-v-27954ba8]{grid-template-columns:1fr}.project-agent-assignment-wide-field[data-v-27954ba8]{grid-column:auto}}.project-agent-dialog-check[data-v-6b96c90d]{align-items:center;gap:7px!important;display:flex!important}.project-agent-dialog-check input[data-v-6b96c90d]{width:auto!important}.project-agent-dialog-note[data-v-6b96c90d]{color:#7b857e;font-size:10px;line-height:1.55}.project-agent-source-state[data-v-f174e20d]{color:#727d75;background:#f7f9f7;border:1px solid #e1e6e2;border-radius:8px;justify-content:space-between;align-items:center;gap:10px;margin-top:22px;padding:10px 12px;font-size:10px;display:flex}.project-agent-source-state.is-error[data-v-f174e20d]{color:#8c4f49;background:#fbf3f1;border-color:#ebd5d0}.project-agent-dialog[data-v-83825f22]{background:0 0;border:0;border-radius:12px;width:min(760px,100vw - 64px);max-height:calc(100vh - 64px);padding:0;overflow:hidden}.project-agent-dialog-shell[data-v-83825f22]{background:#fbfcfb;border:1px solid #d5dcd7;border-radius:12px;flex-direction:column;min-height:0;max-height:calc(100vh - 64px);display:flex;overflow:hidden;box-shadow:0 18px 48px #212d262e}.project-agent-dialog-header[data-v-83825f22],.project-agent-dialog-actions[data-v-83825f22]{justify-content:space-between;align-items:center;gap:16px;padding:18px 20px;display:flex}.project-agent-dialog-header[data-v-83825f22]{border-bottom:1px solid #e1e6e2}.project-agent-dialog-header h3[data-v-83825f22]{color:#283a31;font-size:17px}.project-agent-dialog-fields[data-v-83825f22]{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;min-height:0;padding:20px;display:grid;overflow:auto}.project-agent-dialog-fields label[data-v-83825f22]{color:#626d66;align-content:start;gap:6px;min-width:0;font-size:11px;font-weight:650;display:grid}.project-agent-dialog-fields input[data-v-83825f22],.project-agent-dialog-fields select[data-v-83825f22],.project-agent-dialog-fields textarea[data-v-83825f22]{color:#28342d;background:#fff;border:1px solid #ccd5ce;border-radius:8px;width:100%;padding:9px 10px;font-size:12px;line-height:1.5}.project-agent-dialog-fields textarea[data-v-83825f22]{resize:vertical}.project-agent-dialog-fields input[data-v-83825f22]:focus-visible,.project-agent-dialog-fields select[data-v-83825f22]:focus-visible,.project-agent-dialog-fields textarea[data-v-83825f22]:focus-visible{outline-offset:1px;outline:2px solid #91a398}.project-agent-wide-field[data-v-83825f22],.project-agent-id-note[data-v-83825f22]{grid-column:1/-1}.project-agent-strategy-fields[data-v-83825f22]{border:1px solid #dfe5e0;border-radius:9px;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;min-width:0;margin:0;padding:12px;display:grid}.project-agent-strategy-fields legend[data-v-83825f22]{color:#59665d;padding:0 5px;font-size:10px;font-weight:700}.project-agent-strategy-fields>small[data-v-83825f22]{color:#818a84;grid-column:1/-1;font-size:9px;line-height:1.5}.project-agent-id-note[data-v-83825f22]{color:#7b847e;margin-top:-8px;font-size:10px}.project-agent-dialog-error[data-v-83825f22]{color:#8b3f38;margin:0 20px;font-size:11px}.project-agent-dialog-actions[data-v-83825f22]{border-top:1px solid #e1e6e2;justify-content:flex-end}.project-agent-primary-action[data-v-83825f22]{color:#fff;background:#344c3d;border:0;border-radius:8px;padding:8px 14px;font-size:12px;font-weight:700}.project-agent-primary-action[data-v-83825f22]:hover{background:#2b4234}.project-agent-primary-action[data-v-83825f22]:focus-visible{outline-offset:2px;outline:2px solid #91a398}.project-agent-primary-action[data-v-83825f22]:disabled,.project-agent-dialog-fields[data-v-83825f22] :disabled{cursor:not-allowed;opacity:.6}@media (width<=720px){.project-agent-dialog-fields[data-v-83825f22]{grid-template-columns:1fr}.project-agent-wide-field[data-v-83825f22],.project-agent-id-note[data-v-83825f22]{grid-column:1}}.project-agents-view[data-v-7dd25330]{flex-direction:column;gap:12px;min-height:0;padding:18px 32px 20px;display:flex;overflow:hidden}.project-agents-header[data-v-7dd25330],.project-agent-section-heading[data-v-7dd25330],.project-agent-section-tools[data-v-7dd25330],.project-agent-detail-actions[data-v-7dd25330],.project-agent-assignment-card header[data-v-7dd25330],.project-agent-task-card header[data-v-7dd25330],.project-agent-learning-card header[data-v-7dd25330],.project-agent-day-detail header[data-v-7dd25330]{justify-content:space-between;align-items:center;gap:12px;display:flex}.project-agents-header h2[data-v-7dd25330]{color:#283a31;font-size:18px}.project-agents-header-meta[data-v-7dd25330]{color:#7a847d;font-size:10px}.project-agents-summary[data-v-7dd25330]{color:#737d76;background:#f9faf9;border:1px solid #d6ddd8;border-radius:10px;gap:18px;padding:9px 14px;font-size:11px;display:flex}.project-agents-summary span[data-v-7dd25330]:first-child{color:#2f493b;font-weight:700}.project-agent-add[data-v-7dd25330]{color:#fff;background:#344c3d;border:0;border-radius:8px;padding:8px 13px;font-size:11px;font-weight:700}.project-agent-add[data-v-7dd25330]:hover{background:#2b4234}.project-agent-add[data-v-7dd25330]:focus-visible,.quiet-button[data-v-7dd25330]:focus-visible{outline-offset:2px;outline:2px solid #91a398}.project-agent-add[data-v-7dd25330]:disabled{cursor:not-allowed;opacity:.55}.project-agents-toolbar[data-v-7dd25330]{grid-template-columns:minmax(220px,300px) minmax(240px,1fr) auto;align-items:center;gap:10px;display:grid}.project-agents-search input[data-v-7dd25330]{color:#2e3932;background:#fff;border:1px solid #cfd7d1;border-radius:8px;width:100%;min-height:34px;padding:7px 10px;font-size:11px}.project-agents-search input[data-v-7dd25330]:focus-visible{outline-offset:1px;outline:2px solid #91a398}.project-agents-status-filter[data-v-7dd25330]{background:#f5f7f5;border:1px solid #d8ded9;border-radius:8px;gap:3px;padding:3px;display:flex}.project-agents-status-filter button[data-v-7dd25330],.quiet-button[data-v-7dd25330]{color:#6d7770;background:0 0;border:0;border-radius:6px;padding:6px 9px;font-size:10px}.project-agents-status-filter button[aria-pressed=true][data-v-7dd25330]{color:#315440;background:#fff;font-weight:700;box-shadow:0 1px 3px #27392f1f}.project-agents-directory[data-v-7dd25330]{background:#fff;border:1px solid #cfd7d1;border-radius:10px;flex:1;grid-template-columns:minmax(360px,.94fr) minmax(390px,1.06fr);min-height:0;display:grid;overflow:hidden}.project-agent-list[data-v-7dd25330]{border-right:1px solid #dfe4e0;min-width:0;min-height:0;overflow:auto}.project-agent-row[data-v-7dd25330]{width:100%;color:inherit;text-align:left;background:#fff;border:0;border-bottom:1px solid #e6eae7;grid-template-columns:minmax(0,1fr) auto;gap:5px 14px;padding:14px 16px;display:grid}.project-agent-row[data-v-7dd25330]:hover{background:#f7f9f7}.project-agent-row.selected[data-v-7dd25330]{background:#edf3ef;box-shadow:inset 3px 0 #64816f}.project-agent-row[data-v-7dd25330]:focus-visible{z-index:1;outline-offset:-3px;outline:2px solid #91a398;position:relative}.project-agent-row-heading[data-v-7dd25330]{align-items:center;gap:7px;min-width:0;display:flex}.project-agent-occupation-emoji[data-v-7dd25330]{flex:none;justify-content:center;align-items:center;min-width:1.2em;font-size:15px;line-height:1;display:inline-flex}.project-agent-row-heading strong[data-v-7dd25330]{color:#293b31;text-overflow:ellipsis;white-space:nowrap;font-size:13px;overflow:hidden}.project-agent-row-heading i[data-v-7dd25330],.project-agent-assignment-card header i[data-v-7dd25330],.project-agent-task-card header i[data-v-7dd25330],.project-agent-learning-card header i[data-v-7dd25330]{color:#66716a;background:#e6eae7;border-radius:999px;flex:none;padding:2px 7px;font-size:9px;font-style:normal;font-weight:700}.project-agent-row-heading i.is-active[data-v-7dd25330]{color:#2f6947;background:#e1eee6}.project-agent-row-heading i.is-archived[data-v-7dd25330]{color:#75695d;background:#eeeae5}.project-agent-kind[data-v-7dd25330]{color:#53647b!important;background:#eef2f7!important}.project-agent-row-id[data-v-7dd25330]{color:#8a938d;overflow-wrap:anywhere;text-align:right;font-size:9px}.project-agent-row-projects[data-v-7dd25330]{flex-wrap:wrap;grid-column:1/-1;gap:4px;display:flex}.project-agent-row-projects b[data-v-7dd25330],.project-agent-tags span[data-v-7dd25330],.project-agent-inline-list span[data-v-7dd25330]{color:#5f6b64;background:#eef1ef;border-radius:999px;padding:3px 7px;font-size:9px;font-weight:650}.project-agent-row-projects em[data-v-7dd25330]{color:#8a938d;font-size:9px;font-style:normal}.project-agent-row-responsibility[data-v-7dd25330]{color:#59645d;text-overflow:ellipsis;white-space:nowrap;grid-column:1/-1;font-size:11px;line-height:1.5;overflow:hidden}.project-agent-row-work[data-v-7dd25330]{color:#59645d;grid-column:1/-1;font-size:10px;line-height:1.5}.project-agent-work-dot[data-v-7dd25330]{background:#4b8d63;border-radius:50%;width:6px;height:6px;margin-right:4px;display:inline-block}.project-agent-row-capabilities[data-v-7dd25330]{flex-wrap:wrap;grid-column:1/-1;gap:5px;min-height:20px;display:flex}.project-agent-row-capabilities b[data-v-7dd25330]{color:#68736c;background:#f1f3f1;border-radius:999px;padding:3px 7px;font-size:9px;font-weight:650}.project-agent-detail[data-v-7dd25330]{min-width:0;min-height:0;padding:20px;overflow:auto;container-type:inline-size}.project-agent-detail>header[data-v-7dd25330]{border-bottom:1px solid #e1e6e2;grid-template-columns:minmax(0,1fr) max-content;align-items:flex-start;gap:16px;padding-bottom:16px;display:grid}.project-agent-detail-heading[data-v-7dd25330]{min-width:0}.project-agent-detail h3[data-v-7dd25330]{color:#263b30;text-wrap:balance;font-size:17px;line-height:1.32}.project-agent-detail header p[data-v-7dd25330]{color:#7a847d;overflow-wrap:anywhere;max-width:72ch;margin-top:5px;font-size:10px;line-height:1.5}.project-agent-detail-actions[data-v-7dd25330]{grid-auto-columns:78px;grid-auto-flow:column;justify-content:end;gap:8px;display:grid}.project-agent-detail-actions .quiet-button[data-v-7dd25330]{white-space:nowrap;width:78px}.project-agent-detail-meta[data-v-7dd25330],.project-agent-compact-meta[data-v-7dd25330]{grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin:16px 0 0;display:grid}.project-agent-detail-meta div[data-v-7dd25330],.project-agent-compact-meta div[data-v-7dd25330]{min-width:0}.project-agent-detail-meta dt[data-v-7dd25330],.project-agent-compact-meta dt[data-v-7dd25330],.project-agent-detail-section h4[data-v-7dd25330]{color:#7a847d;letter-spacing:.06em;text-transform:uppercase;font-size:9px;font-weight:700}.project-agent-detail-meta dd[data-v-7dd25330],.project-agent-compact-meta dd[data-v-7dd25330]{overflow-wrap:anywhere;color:#39483f;margin:4px 0 0;font-size:11px}.project-agent-detail-meta dd small[data-v-7dd25330]{color:#818a84;margin-top:3px;font-size:9px;line-height:1.4;display:block}.project-agent-detail-section[data-v-7dd25330]{margin-top:22px}.project-agent-detail-section.is-responsibility[data-v-7dd25330]{background:#f2f5f2;border-radius:10px;padding:14px}.project-agent-detail-section p[data-v-7dd25330],.project-agent-detail-section li[data-v-7dd25330]{color:#4f5c54;font-size:11px;line-height:1.65}.project-agent-tags[data-v-7dd25330],.project-agent-inline-list[data-v-7dd25330]{flex-wrap:wrap;gap:6px;margin-top:9px;display:flex}.project-agent-muted[data-v-7dd25330]{color:#8a928d!important}.project-agent-detail-notice[data-v-7dd25330]{background:#f5f5f1;border-radius:7px;margin:12px 0 0;padding:8px 10px;color:#6f705f!important}.project-agent-detail-placeholder[data-v-7dd25330],.project-agents-state[data-v-7dd25330]{color:#737d76;text-align:center;place-content:center;justify-items:center;gap:8px;min-height:240px;font-size:11px;display:grid}.project-agents-state[data-v-7dd25330]{background:#fafbfa;border:1px solid #d9dfda;border-radius:10px;flex:1}.project-agents-state strong[data-v-7dd25330]{color:#36473e;font-size:14px}.project-agents-state p[data-v-7dd25330]{max-width:52ch;line-height:1.6}.project-agents-state.is-error[data-v-7dd25330]{color:#8b3f38}.project-agent-assignment-list[data-v-7dd25330],.project-agent-task-list[data-v-7dd25330],.project-agent-learning-list[data-v-7dd25330],.project-agent-recruitment-list[data-v-7dd25330]{gap:8px;margin-top:9px;display:grid}.project-agent-execution-summary[data-v-7dd25330]{border-top:1px solid #dfe5e0;margin-top:13px;padding-top:12px}.project-agent-worker-event-evidence[data-v-7dd25330]{background:#f8faf8;border:1px dashed #d8dfd9;border-radius:8px;margin-top:13px;padding:10px 10px 0}.project-agent-execution-summary .project-agent-section-heading[data-v-7dd25330]{gap:8px}.project-agent-execution-summary h5[data-v-7dd25330]{color:#65736a;letter-spacing:.06em;text-transform:uppercase;margin:0;font-size:9px;font-weight:700}.project-agent-execution-summary-list[data-v-7dd25330]{margin:7px 0 0;padding:0;list-style:none;display:grid}.project-agent-execution-summary-row[data-v-7dd25330]{border-top:1px solid #e6ebe7;min-width:0;padding:10px 0}.project-agent-execution-summary-row[data-v-7dd25330]:first-child{border-top:0}.project-agent-execution-summary-row header[data-v-7dd25330]{align-items:flex-start}.project-agent-execution-summary-row header strong[data-v-7dd25330]{overflow-wrap:anywhere;color:#3f5647;align-items:center;gap:5px;min-width:0;font-size:10px;display:flex}.project-agent-execution-summary-row header strong small[data-v-7dd25330]{color:#89948c;margin:0;font-size:8px;font-weight:500;display:inline}.project-agent-execution-summary-row header i[data-v-7dd25330]{color:#66716a;background:#e6eae7;border-radius:999px;flex:none;padding:2px 6px;font-size:8px;font-style:normal;font-weight:700}.project-agent-execution-summary-row header i.is-completed[data-v-7dd25330]{color:#2f6947;background:#e1eee6}.project-agent-execution-summary-row header i.is-failed[data-v-7dd25330]{color:#8c4f49;background:#f7e9e6}.project-agent-execution-summary-row header i.is-cancelled[data-v-7dd25330]{color:#75695d;background:#eeeae5}.project-agent-execution-summary-meta[data-v-7dd25330]{grid-template-columns:repeat(2,minmax(0,1fr));gap:7px 10px;margin:8px 0 0;display:grid}.project-agent-execution-summary-meta div[data-v-7dd25330]{min-width:0}.project-agent-execution-summary-meta dt[data-v-7dd25330]{color:#89948c;letter-spacing:.04em;text-transform:uppercase;font-size:8px;font-weight:700}.project-agent-execution-summary-meta dd[data-v-7dd25330]{overflow-wrap:anywhere;color:#4f5e54;margin:2px 0 0;font-size:9px;line-height:1.45}.project-agent-execution-summary-meta dd small[data-v-7dd25330]{color:#89948c;margin-top:2px;font-size:8px;display:block}.project-agent-assignment-card[data-v-7dd25330],.project-agent-task-card[data-v-7dd25330],.project-agent-learning-card[data-v-7dd25330],.project-agent-recruitment-card[data-v-7dd25330]{background:#fbfcfb;border:1px solid #e0e6e1;border-radius:9px;padding:11px 12px}.project-agent-assignment-card header strong[data-v-7dd25330],.project-agent-task-card header strong[data-v-7dd25330],.project-agent-learning-card header strong[data-v-7dd25330]{color:#33483a;font-size:11px}.project-agent-card-actions[data-v-7dd25330]{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:4px;display:flex}.project-agent-assignment-card p[data-v-7dd25330],.project-agent-task-card p[data-v-7dd25330],.project-agent-learning-card p[data-v-7dd25330]{margin:7px 0 0}.project-agent-assignment-card small[data-v-7dd25330],.project-agent-task-card small[data-v-7dd25330],.project-agent-learning-card small[data-v-7dd25330]{color:#818a84;margin-top:6px;font-size:9px;line-height:1.5;display:block}.project-agent-assignment-card header i.is-ended[data-v-7dd25330],.project-agent-assignment-card header i.is-replaced[data-v-7dd25330]{color:#75695d;background:#eeeae5}.project-agent-strategy-note[data-v-7dd25330],.project-agent-execution-line[data-v-7dd25330]{color:#7a847d;flex-wrap:wrap;align-items:baseline;gap:6px;margin-top:8px;font-size:9px;display:flex}.project-agent-strategy-note strong[data-v-7dd25330],.project-agent-execution-line strong[data-v-7dd25330]{color:#53685a;font-size:10px}.project-agent-strategy-note small[data-v-7dd25330]{color:#8c5d54;flex-basis:100%}.project-agent-routing-decision[data-v-7dd25330]{color:#65736a;background:#f3f7f3;border-left:3px solid #7c9c86;border-radius:0 7px 7px 0;gap:5px;margin-top:10px;padding:9px 10px;font-size:9px;display:grid}.project-agent-routing-decision .project-agent-section-heading[data-v-7dd25330]{align-items:baseline;gap:8px}.project-agent-routing-decision .project-agent-section-heading strong[data-v-7dd25330]{color:#3f604b;font-size:10px}.project-agent-routing-decision small[data-v-7dd25330]{color:#65736a;line-height:1.45}.project-agent-blocked[data-v-7dd25330]{color:#8c5d54!important}.project-agent-task-card header[data-v-7dd25330]{align-items:flex-start}.project-agent-task-card header small[data-v-7dd25330]{margin-top:3px}.project-agent-task-card header i[data-v-7dd25330]{color:#53647b;background:#eef2f7}.project-agent-task-card header i.is-completed[data-v-7dd25330]{color:#2f6947;background:#e1eee6}.project-agent-task-card header i.is-failed[data-v-7dd25330]{color:#8c4f49;background:#f7e9e6}.project-agent-task-card header i.is-cancelled[data-v-7dd25330]{color:#75695d;background:#eeeae5}.project-agent-heatmap-viewport[data-v-7dd25330]{contain:layout inline-size paint;min-width:0;max-width:100%;overflow-x:clip}.project-agent-heatmap[data-v-7dd25330]{grid-template-rows:repeat(7,minmax(10px,1fr));grid-auto-columns:minmax(10px,1fr);grid-auto-flow:column;gap:3px;width:100%;max-width:100%;margin-top:9px;padding:0;display:grid;overflow-x:auto}.project-agent-heat-cell[data-v-7dd25330]{appearance:none;box-sizing:border-box;aspect-ratio:1;background:#f2f4f2;border:1px solid #dfe6e0;border-radius:3px;min-width:9px;margin:0;padding:0}.project-agent-heat-cell.intensity-1[data-v-7dd25330]{background:#dce9df}.project-agent-heat-cell.intensity-2[data-v-7dd25330]{background:#b9d3bf}.project-agent-heat-cell.intensity-3[data-v-7dd25330]{background:#87b493}.project-agent-heat-cell.intensity-4[data-v-7dd25330]{background:#548466}.project-agent-heat-cell[data-v-7dd25330]:focus-visible,.project-agent-heat-cell.selected[data-v-7dd25330]{box-shadow:none;border:2px solid #2f5740;outline:none}.project-agent-day-detail[data-v-7dd25330]{background:#f6f8f6;border-radius:8px;margin-top:10px;padding:10px}.project-agent-day-detail ul[data-v-7dd25330]{margin:8px 0 0;padding-left:17px}.project-agent-day-detail li[data-v-7dd25330]{margin-top:6px}.project-agent-day-detail li strong[data-v-7dd25330],.project-agent-day-detail li span[data-v-7dd25330],.project-agent-day-detail li small[data-v-7dd25330]{display:block}.project-agent-day-detail li span[data-v-7dd25330]{color:#66736b;font-size:9px}.project-agent-day-detail li small[data-v-7dd25330]{color:#7e8981;font-size:9px}.project-agent-client-list[data-v-7dd25330],.project-agent-rule-list[data-v-7dd25330]{gap:5px;margin-top:9px;display:grid}.project-agent-client-row[data-v-7dd25330],.project-agent-rule-row[data-v-7dd25330]{color:#68736c;background:#f7f9f7;border-radius:7px;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:7px;padding:8px 10px;font-size:9px;display:grid}.project-agent-client-row strong[data-v-7dd25330],.project-agent-rule-row strong[data-v-7dd25330]{color:#43584a;font-size:10px}.project-agent-client-row small[data-v-7dd25330]{color:#8a938d;grid-column:1/-1}.project-agent-executor-list[data-v-7dd25330]{gap:5px;margin-top:9px;display:grid}.project-agent-executor-row[data-v-7dd25330]{color:#68736c;background:#f7f9f7;border-radius:7px;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:7px;padding:8px 10px;font-size:9px;display:grid}.project-agent-executor-row strong[data-v-7dd25330]{color:#43584a;font-size:10px}.project-agent-executor-row small[data-v-7dd25330]{color:#8a938d;grid-column:1/-1}.project-agent-learning-card header i[data-v-7dd25330]{color:#6c776f;background:#f1f3f1}.project-agent-evidence-list[data-v-7dd25330]{margin:8px 0 0;padding-left:17px}.project-agent-evidence-list li[data-v-7dd25330]{color:#768179;font-size:9px}.project-agent-learning-actions[data-v-7dd25330]{gap:6px;margin-top:8px;display:flex}.project-agent-note[data-v-7dd25330]{color:#818a84;margin-top:9px;font-size:9px;line-height:1.5;display:block}.sr-only[data-v-7dd25330]{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}@media (width<=1180px){.project-agents-toolbar[data-v-7dd25330]{grid-template-columns:minmax(220px,280px) 1fr}.project-agents-status-filter[data-v-7dd25330]{grid-column:1/-1;justify-self:start}.project-agents-directory[data-v-7dd25330]{grid-template-columns:minmax(320px,.9fr) minmax(330px,1fr)}.project-agent-detail-meta[data-v-7dd25330],.project-agent-compact-meta[data-v-7dd25330]{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (width<=420px){.project-agent-detail>header[data-v-7dd25330]{grid-template-columns:minmax(0,1fr)}.project-agent-detail-actions[data-v-7dd25330]{justify-content:start}}@media (width<=760px){.project-agents-view[data-v-7dd25330]{padding:14px 16px 18px;overflow:auto}.project-agents-header[data-v-7dd25330],.project-agents-summary[data-v-7dd25330],.project-agent-section-heading[data-v-7dd25330],.project-agent-assignment-card header[data-v-7dd25330]{flex-wrap:wrap;align-items:flex-start}.project-agents-toolbar[data-v-7dd25330]{grid-template-columns:minmax(0,1fr)}.project-agents-project-filter[data-v-7dd25330],.project-agents-search[data-v-7dd25330],.project-agents-status-filter[data-v-7dd25330]{grid-column:1}.project-agents-status-filter[data-v-7dd25330]{flex-wrap:wrap;justify-self:stretch;width:100%}.project-agents-directory[data-v-7dd25330]{flex:none;grid-template-columns:minmax(0,1fr);overflow:visible}.project-agent-list[data-v-7dd25330]{border-bottom:1px solid #dfe4e0;border-right:0;max-height:340px}.project-agent-detail[data-v-7dd25330]{min-height:520px;padding:16px}.project-agent-client-row[data-v-7dd25330],.project-agent-rule-row[data-v-7dd25330],.project-agent-executor-row[data-v-7dd25330]{grid-template-columns:minmax(0,1fr);align-items:start}.project-agent-client-row small[data-v-7dd25330],.project-agent-executor-row small[data-v-7dd25330]{grid-column:1}.project-agent-execution-summary-meta[data-v-7dd25330]{grid-template-columns:minmax(0,1fr)}.project-agent-execution-summary-row header[data-v-7dd25330]{gap:8px}}
|