@undefineds.co/linx 0.2.15 → 0.2.16

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 (41) hide show
  1. package/README.md +3 -6
  2. package/dist/index.js +50 -104
  3. package/dist/index.js.map +1 -1
  4. package/dist/lib/ai-command.js +38 -60
  5. package/dist/lib/ai-command.js.map +1 -1
  6. package/dist/lib/pi-adapter/branding.js +2 -2
  7. package/dist/lib/pi-adapter/branding.js.map +1 -1
  8. package/dist/lib/pi-adapter/pod-native.js +3 -2
  9. package/dist/lib/pi-adapter/pod-native.js.map +1 -1
  10. package/dist/lib/pi-adapter/runtime.js +2 -2
  11. package/dist/lib/pi-adapter/runtime.js.map +1 -1
  12. package/dist/lib/pod-data-session.js +43 -3
  13. package/dist/lib/pod-data-session.js.map +1 -1
  14. package/dist/lib/watch/hooks/claude.js +4 -0
  15. package/dist/lib/watch/hooks/claude.js.map +1 -1
  16. package/dist/lib/watch/hooks/codebuddy.js +4 -0
  17. package/dist/lib/watch/hooks/codebuddy.js.map +1 -1
  18. package/dist/lib/watch/hooks/codex.js +4 -0
  19. package/dist/lib/watch/hooks/codex.js.map +1 -1
  20. package/dist/lib/watch/pod-ai.js +22 -14
  21. package/dist/lib/watch/pod-ai.js.map +1 -1
  22. package/dist/lib/watch/pod-approval.js +387 -35
  23. package/dist/lib/watch/pod-approval.js.map +1 -1
  24. package/dist/lib/watch/pod-persistence.js +162 -43
  25. package/dist/lib/watch/pod-persistence.js.map +1 -1
  26. package/dist/lib/watch/runner.js +240 -38
  27. package/dist/lib/watch/runner.js.map +1 -1
  28. package/dist/lib/watch/secretary.js +238 -0
  29. package/dist/lib/watch/secretary.js.map +1 -0
  30. package/dist/watch-cli.js +8 -34
  31. package/dist/watch-cli.js.map +1 -1
  32. package/package.json +3 -2
  33. package/vendor/agent-runtime/dist/acp.d.ts +27 -0
  34. package/vendor/agent-runtime/dist/acp.js +86 -0
  35. package/vendor/agent-runtime/dist/companion-model.d.ts +7 -0
  36. package/vendor/agent-runtime/dist/companion-model.js +12 -0
  37. package/vendor/agent-runtime/dist/index.d.ts +3 -0
  38. package/vendor/agent-runtime/dist/index.js +3 -0
  39. package/vendor/agent-runtime/dist/turn-controller.d.ts +69 -0
  40. package/vendor/agent-runtime/dist/turn-controller.js +129 -0
  41. package/vendor/agent-runtime/package.json +11 -0
@@ -0,0 +1,129 @@
1
+ function normalizeMentionToken(value) {
2
+ return value.trim().toLowerCase();
3
+ }
4
+ function uniqueStrings(values) {
5
+ return Array.from(new Set(values.filter(Boolean)));
6
+ }
7
+ export function findMentionedGroupAgents(message, agents) {
8
+ const normalizedMessage = message.toLowerCase();
9
+ return agents.filter((agent) => {
10
+ const candidates = uniqueStrings([
11
+ agent.id,
12
+ agent.name,
13
+ ...(agent.aliases ?? []),
14
+ ]).map(normalizeMentionToken);
15
+ return candidates.some((candidate) => candidate && normalizedMessage.includes(`@${candidate}`));
16
+ });
17
+ }
18
+ export async function routeGroupTurn(input) {
19
+ const coordinationId = input.coordinationId ?? `group-turn-${Date.now()}`;
20
+ const agents = input.agents.filter((agent) => agent.id && agent.name);
21
+ if (agents.length === 0) {
22
+ return {
23
+ shouldReply: false,
24
+ targetAgentIds: [],
25
+ routedBy: 'none',
26
+ coordinationId,
27
+ reason: 'No AI agent participants are available.',
28
+ };
29
+ }
30
+ const mentionedAgents = findMentionedGroupAgents(input.latestUserMessage, agents);
31
+ if (mentionedAgents.length > 0) {
32
+ return {
33
+ shouldReply: true,
34
+ targetAgentIds: mentionedAgents.map((agent) => agent.id),
35
+ routedBy: 'mention',
36
+ coordinationId,
37
+ reason: 'User explicitly mentioned one or more AI agents.',
38
+ confidence: 1,
39
+ };
40
+ }
41
+ if (agents.length === 1) {
42
+ return {
43
+ shouldReply: true,
44
+ targetAgentIds: [agents[0].id],
45
+ routedBy: 'single-agent',
46
+ coordinationId,
47
+ reason: 'Only one AI agent is present in the group.',
48
+ confidence: 1,
49
+ };
50
+ }
51
+ if (!input.decide) {
52
+ return {
53
+ shouldReply: false,
54
+ targetAgentIds: [],
55
+ routedBy: 'none',
56
+ coordinationId,
57
+ reason: 'No group turn controller is available for unmentioned multi-agent routing.',
58
+ };
59
+ }
60
+ const decision = await input.decide({
61
+ latestUserMessage: input.latestUserMessage,
62
+ agents,
63
+ history: input.history ?? [],
64
+ });
65
+ const validAgentIds = new Set(agents.map((agent) => agent.id));
66
+ const targetAgentIds = uniqueStrings(decision.targetAgentIds).filter((id) => validAgentIds.has(id));
67
+ return {
68
+ shouldReply: decision.shouldReply && targetAgentIds.length > 0,
69
+ targetAgentIds,
70
+ routedBy: 'controller',
71
+ coordinationId,
72
+ reason: decision.reason,
73
+ confidence: decision.confidence,
74
+ };
75
+ }
76
+ export const GROUP_AGENT_TURN_RULE = {
77
+ id: 'chat.group.agent-turn',
78
+ trigger: 'user.message',
79
+ targetAgent: 'agent-turn-controller',
80
+ targetRole: 'system',
81
+ context: {
82
+ recentMessages: 24,
83
+ includeToolCalls: false,
84
+ includeToolResults: false,
85
+ includeSystemEvents: false,
86
+ },
87
+ allowedOutputs: ['chat_message'],
88
+ requiresUserVisibleTrace: false,
89
+ };
90
+ export const WATCH_SECRETARY_APPROVAL_RULE = {
91
+ id: 'watch.secretary.approval',
92
+ trigger: 'approval.required',
93
+ targetAgent: 'ai-secretary',
94
+ targetRole: 'secretary',
95
+ requiredCapabilities: ['approval.request', 'approval.options'],
96
+ context: {
97
+ recentMessages: 24,
98
+ includeCurrentApproval: true,
99
+ includeMatchingGrants: true,
100
+ includeToolCalls: true,
101
+ includeToolResults: true,
102
+ includeSystemEvents: false,
103
+ },
104
+ allowedOutputs: ['chat_message', 'approval_decision', 'control_command'],
105
+ allowedControls: ['inject_message', 'pause', 'stop'],
106
+ requiresUserVisibleTrace: true,
107
+ };
108
+ export const WATCH_SECRETARY_INPUT_RULE = {
109
+ id: 'watch.secretary.input',
110
+ trigger: 'input.required',
111
+ targetAgent: 'ai-secretary',
112
+ targetRole: 'secretary',
113
+ requiredCapabilities: ['input.structured'],
114
+ context: {
115
+ recentMessages: 24,
116
+ includeCurrentApproval: false,
117
+ includeMatchingGrants: false,
118
+ includeToolCalls: true,
119
+ includeToolResults: true,
120
+ includeSystemEvents: false,
121
+ },
122
+ allowedOutputs: ['chat_message', 'input_answer', 'control_command'],
123
+ allowedControls: ['inject_message'],
124
+ requiresUserVisibleTrace: true,
125
+ };
126
+ export const DEFAULT_WATCH_SECRETARY_RULES = [
127
+ WATCH_SECRETARY_APPROVAL_RULE,
128
+ WATCH_SECRETARY_INPUT_RULE,
129
+ ];
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "@linx/agent-runtime",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": "./dist/index.js",
7
+ "./acp": "./dist/acp.js",
8
+ "./companion-model": "./dist/companion-model.js",
9
+ "./turn-controller": "./dist/turn-controller.js"
10
+ }
11
+ }