-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSkills.tish
More file actions
86 lines (79 loc) · 2.9 KB
/
Copy pathSkills.tish
File metadata and controls
86 lines (79 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Co-DJ skill registry: skills gate which deck lines each actor (lane) may emit.
// Single home for skill logic — Merge.tish and the incremental stream apply both gate through here.
/** True if skillIds includes the given skill. */
export fn hasSkill(skillIds, id) {
if (!Array.isArray(skillIds)) {
return false
}
let i = 0
while (i < skillIds.length) {
if (skillIds[i] === id) {
return true
}
i = i + 1
}
return false
}
/** True if these skills carry master rights (bpm / auto / transpose / scene / clip). */
export fn skillIdsAllowMaster(skillIds) {
return hasSkill(skillIds, "master_mixer")
}
/**
* Check if an actor with skillIds may emit this deck line.
* Global / master-scope lines require the master_mixer skill; everything else is allowed (per-track
* ownership is enforced separately by Merge.tish:actorMayEditTrack). Master-scope = anything that changes
* the WHOLE session for every player: bpm, tpl re-header, auto, transpose, master_mix, actor_mix,
* session_scenes/session_slot, clip, AND the global key/groove (scale, swing) — a co-DJ lane must not
* re-key or re-shuffle the whole mix out from under the host. Keep this list in lockstep with
* docs/DJ_SKILLS.md and the agent SYSTEM_PROMPT (services/agent-worker/main.tish).
*/
export fn coDjLineAllowedForSkills(line, skillIds) {
let t = line.trim()
if (t.length === 0 || t.charAt(0) === "#") {
return true
}
let sp = t.indexOf(" ")
let h = sp < 0 ? t : t.substring(0, sp)
if (
h === "bpm" ||
h === "deck" ||
h === "tpl" ||
h === "auto" ||
h === "transpose" ||
h === "master_mix" ||
h === "actor_mix" ||
h === "session_scenes" ||
h === "session_slot" ||
h === "clip" ||
h === "scale" ||
h === "swing"
) {
return skillIdsAllowMaster(skillIds)
}
return true
}
/** Back-compat facade name. */
fn skillAllowsLine(line, skillIds) {
return coDjLineAllowedForSkills(line, skillIds)
}
fn skillHumanOk(id) {
if (id === "add_track") return true
if (id === "adjust_instrument") return true
if (id === "pattern_steps") return true
if (id === "pattern_piano") return true
if (id === "channel_mix") return true
if (id === "master_mixer") return true
if (id === "transpose_track" || id === "promote_song" || id === "remove_track") return false
return false
}
fn skillAiOk(id) {
if (id === "master_mixer" || id === "transpose_track" || id === "promote_song" || id === "remove_track") return false
if (id === "add_track" || id === "adjust_instrument" || id === "pattern_steps" || id === "pattern_piano" || id === "channel_mix") return true
return false
}
/** True if an actor with this skillId may use it. Human-like actors get skillHumanOk; agent-like get skillAiOk. */
fn actorHasSkill(skillId, actorId) {
if (!actorId || typeof actorId !== "string") return false
if (actorId.indexOf("agent") >= 0) return skillAiOk(skillId)
return skillHumanOk(skillId)
}