house-lights 1.2.1 → 1.3.0

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 (54) hide show
  1. package/package.json +1 -1
  2. package/skills/cast-list/assets/map.html +56 -30
  3. package/skills/cast-list/examples/agents/bodega-cupons/actions/AbrirChamadoERP.mcs.yml +15 -0
  4. package/skills/cast-list/examples/agents/bodega-cupons/actions/ConsultarCuponsAtivos.mcs.yml +1 -1
  5. package/skills/cast-list/examples/agents/bodega-cupons/actions/EnviarCupomEmail.mcs.yml +1 -1
  6. package/skills/cast-list/examples/agents/bodega-cupons/actions/PromocoesMCP.mcs.yml +1 -1
  7. package/skills/cast-list/examples/agents/bodega-cupons/agent.mcs.yml +12 -0
  8. package/skills/cast-list/examples/agents/bodega-cupons/connectionreferences.mcs.yml +7 -7
  9. package/skills/cast-list/examples/agents/bodega-cupons/topics/ConsultarRegulamentoCupons.topic.mcs.yml +3 -3
  10. package/skills/cast-list/examples/agents/bodega-cupons/topics/Escalate.topic.mcs.yml +1 -1
  11. package/skills/cast-list/examples/agents/bodega-cupons/topics/Fallback.topic.mcs.yml +5 -5
  12. package/skills/cast-list/examples/agents/bodega-cupons/topics/Greeting.topic.mcs.yml +1 -1
  13. package/skills/cast-list/examples/agents/bodega-cupons/topics/OnError.topic.mcs.yml +7 -7
  14. package/skills/cast-list/examples/agents/bodega-cupons/topics/RecebimentoOrquestrador.topic.mcs.yml +1 -1
  15. package/skills/cast-list/examples/agents/bodega-devolucoes/actions/AbrirChamadoERP.mcs.yml +15 -0
  16. package/skills/cast-list/examples/agents/bodega-devolucoes/actions/AbrirSolicitacaoDevolucao.mcs.yml +1 -1
  17. package/skills/cast-list/examples/agents/bodega-devolucoes/agent.mcs.yml +13 -0
  18. package/skills/cast-list/examples/agents/bodega-devolucoes/connectionreferences.mcs.yml +2 -2
  19. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/ConsultarPoliticaDevolucoes.topic.mcs.yml +3 -3
  20. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/Escalate.topic.mcs.yml +1 -1
  21. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/Fallback.topic.mcs.yml +5 -5
  22. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/Greeting.topic.mcs.yml +1 -1
  23. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/OnError.topic.mcs.yml +7 -7
  24. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/RecebimentoOrquestrador.topic.mcs.yml +1 -1
  25. package/skills/cast-list/examples/agents/bodega-frete/actions/EnviarOpcoesFrete.mcs.yml +1 -1
  26. package/skills/cast-list/examples/agents/bodega-frete/agent.mcs.yml +7 -0
  27. package/skills/cast-list/examples/agents/bodega-frete/connectionreferences.mcs.yml +2 -2
  28. package/skills/cast-list/examples/agents/bodega-frete/topics/ConsultarTabelaFrete.topic.mcs.yml +3 -3
  29. package/skills/cast-list/examples/agents/bodega-frete/topics/Desambiguar.topic.mcs.yml +11 -0
  30. package/skills/cast-list/examples/agents/bodega-frete/topics/Fallback.topic.mcs.yml +5 -5
  31. package/skills/cast-list/examples/agents/bodega-frete/topics/Greeting.topic.mcs.yml +1 -1
  32. package/skills/cast-list/examples/agents/bodega-frete/topics/OnError.topic.mcs.yml +7 -7
  33. package/skills/cast-list/examples/agents/bodega-frete/topics/RecebimentoOrquestrador.topic.mcs.yml +1 -1
  34. package/skills/cast-list/examples/agents/bodega-loja-fisica/actions/EnviarInstrucoesRetirada.mcs.yml +1 -1
  35. package/skills/cast-list/examples/agents/bodega-loja-fisica/agent.mcs.yml +12 -0
  36. package/skills/cast-list/examples/agents/bodega-loja-fisica/connectionreferences.mcs.yml +2 -2
  37. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/ConsultarGuiaLojaFisica.topic.mcs.yml +3 -3
  38. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/Escalate.topic.mcs.yml +1 -1
  39. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/Fallback.topic.mcs.yml +5 -5
  40. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/Greeting.topic.mcs.yml +1 -1
  41. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/OnError.topic.mcs.yml +6 -6
  42. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/RecebimentoOrquestrador.topic.mcs.yml +1 -1
  43. package/skills/cast-list/examples/agents/bodega-orquestrador/agent.mcs.yml +2 -0
  44. package/skills/cast-list/examples/agents/bodega-pedidos/actions/AbrirChamadoERP.mcs.yml +15 -0
  45. package/skills/cast-list/examples/agents/bodega-pedidos/actions/EnviarResumoPedido.mcs.yml +1 -1
  46. package/skills/cast-list/examples/agents/bodega-pedidos/agent.mcs.yml +10 -0
  47. package/skills/cast-list/examples/agents/bodega-pedidos/connectionreferences.mcs.yml +2 -2
  48. package/skills/cast-list/examples/agents/bodega-pedidos/topics/ConsultarPoliticasPedidos Copy.topic.mcs.yml +56 -0
  49. package/skills/cast-list/examples/profile.cast.yaml +28 -0
  50. package/skills/cast-list/references/format.md +10 -3
  51. package/skills/cast-list/references/keys.md +12 -0
  52. package/skills/cast-list/references/profile.md +35 -0
  53. package/skills/cast-list/scripts/build.mjs +6 -4
  54. package/skills/cast-list/scripts/engine.mjs +126 -123
@@ -0,0 +1,56 @@
1
+ mcs.metadata:
2
+ componentName: Consultar Políticas de Pedidos Copy
3
+ description: "Responde dúvidas sobre pedidos com base nas políticas publicadas no SharePoint."
4
+ kind: AdaptiveDialog
5
+ inputs:
6
+ - kind: AutomaticTaskInput
7
+ propertyName: PerguntaCliente
8
+ description: "A pergunta do cliente sobre pedidos, status, cancelamento ou pagamento."
9
+ shouldPromptUser: true
10
+
11
+ modelDescription: "Responde perguntas sobre status de pedido, prazos de processamento, cancelamento antes do envio e formas de pagamento da Bodega Azul."
12
+ beginDialog:
13
+ kind: OnRecognizedIntent
14
+ id: main
15
+ intent: {}
16
+ actions:
17
+ - kind: CreateSearchQuery
18
+ id: createSearchQuery_LQyhy8
19
+ userInput: =Topic.PerguntaCliente
20
+ result: Topic.SearchQuery
21
+
22
+ - kind: SearchAndSummarizeContent
23
+ id: searchContent_O7ySob
24
+ autoSend: false
25
+ variable: Topic.SearchResult
26
+ userInput: =Topic.SearchQuery.SearchQuery
27
+ fileSearchDataSource:
28
+ searchFilesMode:
29
+ kind: DoNotSearchFiles
30
+
31
+ knowledgeSources:
32
+ kind: SearchSpecificKnowledgeSources
33
+ knowledgeSources:
34
+ - cr7b2_bodegaPedidos.knowledge.PoliticasPedidos
35
+
36
+ applyModelKnowledgeSetting: false
37
+ responseCaptureType: FullResponse
38
+
39
+ - kind: SetVariable
40
+ id: setVariable_f4lXT8
41
+ variable: Topic.Resposta
42
+ value: =Topic.SearchResult.Text.Content
43
+
44
+ inputType:
45
+ properties:
46
+ PerguntaCliente:
47
+ displayName: PerguntaCliente
48
+ description: "A pergunta do cliente sobre pedidos, status, cancelamento ou pagamento."
49
+ type: String
50
+
51
+ outputType:
52
+ properties:
53
+ Resposta:
54
+ displayName: Resposta
55
+ description: Resposta fundamentada na base de conhecimento do agente.
56
+ type: String
@@ -9,6 +9,34 @@ min_agents: 3 # …with at least 3 agents in that role
9
9
  rules:
10
10
  - { id: escala, role: specialist, has: "trigger:OnEscalate", says: "Todo especialista escala para humano" }
11
11
  - { id: kpi, role: specialist, has: "declared:kpi", says: "Todo especialista tem KPI" }
12
+ # what the text says against how the agent is set up
13
+ - { id: knowledge-only, when: "text:knowledge-only", not: "setting:model-knowledge=on",
14
+ says: "Quem pede só o conhecimento tem o conhecimento geral desligado" }
15
+
16
+ # what to look for in the text (JavaScript regular expressions; case does not matter)
17
+ markers:
18
+ - { id: size, name: Tamanho da resposta, in: instructions,
19
+ pattern: '(no máximo|at most|up to)\s*(\d+)\s*(bullets?|frases?|sentences?)', value: "$2 $3" }
20
+ - { id: no-emoji, name: Sem emojis, pattern: '(sem|não use|no)\s+emojis?' }
21
+ - { id: knowledge-only, name: Só o conhecimento, pattern: '(somente|apenas|only)[^.]{0,40}(conhecimento|knowledge)' }
22
+
23
+ # the block the team pastes in every specialist
24
+ blocks:
25
+ - id: links
26
+ name: Formatação de links
27
+ text: |
28
+ Links:
29
+ - Formate links assim: [título](url), nunca a URL crua.
30
+ - Um link de ação vai no topo; o link da base de ajuda vai no fim.
31
+ - Nunca escreva as palavras «clique aqui».
32
+ - No máximo 3 links por resposta.
33
+
34
+ # the kinds of specialist: one may be of two types; patterns are also found within each type
35
+ types:
36
+ - { id: transaction, name: transação, when: { any: ["flow:*"] } }
37
+ - { id: guidance, name: orientação, when: { all: ["text:link-domain:*", "node:SearchAndSummarizeContent"] } }
38
+ - { id: triage, name: triagem, when: { any: ["trigger:OnSelectIntent"] } }
39
+
12
40
  focus_areas:
13
41
  - { id: confiabilidade, name: Confiabilidade, facts: ["trigger:OnError", "node:LogCustomTelemetryEvent", "ms:rai-error-handling"] }
14
42
  ignore: ["trigger:OnConversationStart"]
@@ -11,7 +11,12 @@ format: cast-list/cast-v1
11
11
  name: Customer service agents
12
12
  agents: # the roles of the last run (an agent the profile does not name keeps its role here)
13
13
  - { id: main-orchestrator, role: orchestrator }
14
- - { id: returns, role: specialist }
14
+ - { id: returns, role: specialist, types: [ transaction ] } # types a person gives win over the profile's
15
+ blocks: # the blocks of text of the last run, so a block keeps its id across small edits
16
+ - id: links
17
+ text: |
18
+ Links:
19
+ - Format links as [title](url), never the bare URL.
15
20
  declared: # what a document or a person says — always with its source
16
21
  - { agent: returns, key: kpi, value: "time to answer < 2 min", source: "backlog, epic 12" }
17
22
  - { agent: shipping, key: "trigger:OnEscalate", value: "yes", source: "handoff, section 4" }
@@ -19,11 +24,13 @@ decisions: # what the team decided about a pattern
19
24
  - { key: "trigger:OnEscalate", status: accepted, scope: platform, why: "Nobody is left without a person" }
20
25
  ```
21
26
 
27
+ - **blocks** and the roles are written by the run; **types** are written only by a person (the ones the profile works
28
+ out are not kept, so a change in the profile still holds).
22
29
  - **declared**: `key` is either something only people know (`kpi`, `owner`, any word: it becomes `declared:<key>`) or a
23
30
  fact key (`trigger:OnEscalate`, `references/keys.md`) when a document claims the agent does it. `value` `no` / `não` /
24
31
  `false` claims it does **not**. A claim never changes what the YAML shows: when they disagree, it is a conflict.
25
- - **decisions**: `status` is `accepted` or `rejected`; `scope` is `platform` (every agent), `specialist` or
26
- `orchestrator`; `why` says it. An accepted pattern is checked on every agent of its scope on the next run — even when
32
+ - **decisions**: `status` is `accepted` or `rejected`; `scope` is `platform` (every agent), `specialist`,
33
+ `orchestrator` or `type:<id>` (the specialists of a type — «tipo:<name>» in the workbook); `why` says it. An accepted pattern is checked on every agent of its scope on the next run — even when
27
34
  its share would no longer make it a pattern. A rejected one is shown and nobody is off it.
28
35
 
29
36
  ## The workbook back
@@ -41,6 +41,10 @@ Every fact cast-list finds is a key. The keys below have a name; any other key k
41
41
  | Key | Name | Nome |
42
42
  |---|---|---|
43
43
  | `trigger:OnKnowledgeRequested` | Before searching knowledge | Antes de buscar no conhecimento |
44
+ | `setting:semantic-search=on` | Semantic search on | Busca semântica ligada |
45
+ | `setting:semantic-search=off` | Semantic search off | Busca semântica desligada |
46
+ | `setting:web-browsing=on` | Web browsing on | Navegação na web ligada |
47
+ | `setting:web-browsing=off` | Web browsing off | Navegação na web desligada |
44
48
  | `node:SearchAndSummarizeContent` | Generative answers from knowledge | Respostas generativas sobre o conhecimento |
45
49
  | `node:SearchKnowledgeSources` | Searches the knowledge sources | Busca nas fontes de conhecimento |
46
50
  | `yaml-only:triggerCondition` | Search condition only in YAML (the editor may erase it) | Condição de busca só no YAML (a tela pode apagar) |
@@ -63,6 +67,8 @@ Every fact cast-list finds is a key. The keys below have a name; any other key k
63
67
 
64
68
  | Key | Name | Nome |
65
69
  |---|---|---|
70
+ | `setting:model-knowledge=on` | The model's general knowledge on | Conhecimento geral do modelo ligado |
71
+ | `setting:model-knowledge=off` | The model's general knowledge off | Conhecimento geral do modelo desligado |
66
72
  | `instructions:present` | Has instructions | Tem instruções |
67
73
  | `node:LogCustomTelemetryEvent` | Logs telemetry | Registra telemetria |
68
74
  | `node:CSATQuestion` | Asks for satisfaction (CSAT) | Pergunta a satisfação (CSAT) |
@@ -70,6 +76,12 @@ Every fact cast-list finds is a key. The keys below have a name; any other key k
70
76
  | `model:<value>` | Model <value> | Modelo <valor> |
71
77
  | `auth:<value>` | Sign-in <value> | Login <valor> |
72
78
 
79
+ ## F. Text — F. Texto
80
+
81
+ | Key | Name | Nome |
82
+ |---|---|---|
83
+ | `text:<value>` | Text: <value> | Texto: <valor> |
84
+
73
85
  ## Microsoft patterns — Padrões Microsoft
74
86
 
75
87
  | Key | Name | Nome |
@@ -29,4 +29,39 @@ microsoft_patterns: on # off leaves the ms: facts out
29
29
  | `focus_areas` | none | Each a filter of the matrix. |
30
30
  | `ignore` | none | Keys that say nothing for this team. |
31
31
 
32
+ ## What to look for in the text, and the types
33
+
34
+ ```yaml
35
+ rules:
36
+ # a condition and a «not»: the text says one thing, the setup another
37
+ - { id: knowledge-only, when: "text:knowledge-only", not: "setting:model-knowledge=on",
38
+ says: "Who asks for the knowledge alone has the model's general knowledge off" }
39
+ markers: # JavaScript regular expressions; case does not matter
40
+ - { id: size, name: Answer size, in: instructions,
41
+ pattern: '(at most|up to|no máximo)\s*(\d+)\s*(bullets?|sentences?|frases?)', value: "$2 $3" }
42
+ - { id: no-emoji, name: No emojis, pattern: '(no|never use|sem)\s+emojis?' }
43
+ - { id: knowledge-only, name: Knowledge only, pattern: '(only|somente)[^.]{0,40}(knowledge|conhecimento)' }
44
+ blocks: # the text the team pastes in every agent of a role
45
+ - id: links
46
+ name: Link formatting
47
+ role: specialist # the default
48
+ text: |
49
+ Links:
50
+ - Format links as [title](url), never the bare URL.
51
+ types: # a specialist gets every type whose «when» its facts match
52
+ - { id: transaction, name: transaction, when: { any: ["flow:*"] } }
53
+ - { id: guidance, name: guidance, when: { all: ["text:link-domain:*", "node:SearchAndSummarizeContent"], none: ["flow:*"] }, min_agents: 2 }
54
+ ```
55
+
56
+ | Field | What it does |
57
+ |---|---|
58
+ | `rules[].when` / `has` / `not` | A rule is for the agents (of its `role`, or all) that have every key of `when`; it is broken when one lacks `has`, or has `not`. A key may end in `*`. A broken `not` rule is said as a contradiction. |
59
+ | `markers` | `in`: `instructions` (the default), `descriptions` (what topics and actions tell the model) or `all`. With no `value`: a fact `text:<id>`. With a `value` (`$1`…`$9` from the regex): `text:<id>=<value>` — agents of a role that set it in different ways are told («unify?»), and one that sets it twice («which one holds?»). Two are built in: `text:link-domain:<host>` for each link in the instructions, `text:email`. In YAML, write a regex in single quotes. |
60
+ | `blocks` | The official text. The family of blocks like it (half of it, at least) takes its id and name; every agent of `role` without it, or with a variation, is off it — with or without a majority. With no `blocks`, the blocks two agents or more share are still found, named by their first words. |
61
+ | `types` | `when` with `all`, `any` (one of), `none`. A specialist may be of two types; the cast file's `types` for an agent win. Patterns are found within each type with its `min_agents` (2 unless said), scope `type:<id>`; a pattern of a type never blames who is not of it. A type with fewer agents is told, and compared in nothing. |
62
+
63
+ A key in `when`, `has`, `not` or a type must start like a real kind of key (`references/keys.md`): a typo is
64
+ `✗ profile:line`, as is a regex that does not compile, an unknown `in`, a type with no `when`, or a rule with
65
+ nothing to check.
66
+
32
67
  The keys are the same in any language; only the screen words change with `--lang`.
@@ -82,11 +82,11 @@ const profile = option('--profile') ? read(resolve(option('--profile')), readPro
82
82
  const out = resolve(option('--out') ?? dirname(folder))
83
83
  const castFile = join(out, `${id}.cast.yaml`)
84
84
  const castText = existsSync(castFile) ? readFileSync(castFile, 'utf8') : undefined
85
- const cast = castText !== undefined ? read(castFile, readCast).cast : { ...(profile.name ? { name: profile.name } : {}), agents: [], declared: [], decisions: [] }
85
+ const cast = castText !== undefined ? read(castFile, readCast).cast : { ...(profile.name ? { name: profile.name } : {}), agents: [], blocks: [], declared: [], decisions: [] }
86
86
 
87
87
  // ---- the way back: an edited workbook as the changes it proposes ----
88
88
  if (argv.includes('--from')) {
89
- const edited = fromSheets(cast, readXlsx(readFileSync(resolve(option('--from')))))
89
+ const edited = fromSheets(cast, readXlsx(readFileSync(resolve(option('--from')))), Object.fromEntries(profile.types.map((t) => [t.id, t.name])))
90
90
  if (edited.problems.length) {
91
91
  for (const p of edited.problems) console.error(`✗ ${basename(option('--from'))}: ${p}`)
92
92
  process.exit(1)
@@ -145,8 +145,10 @@ const all = argv.includes('--all')
145
145
  const want = { html: all || argv.includes('--html'), xlsx: all || argv.includes('--xlsx'), lesson: all || argv.includes('--lesson') }
146
146
  if (!want.xlsx && !want.lesson) want.html = true
147
147
  mkdirSync(out, { recursive: true })
148
- // the cast file keeps this run's roles, under what people wrote in it
149
- const kept = { ...cast, agents: result.agents.map((a) => ({ id: a.id, role: a.role })) }
148
+ // the cast file keeps this run's roles and blocks of text (so a block keeps its id across small edits), under what
149
+ // people wrote in it; the types a person gave an agent stay, the ones the profile works out are not written
150
+ const givenTypes = Object.fromEntries(cast.agents.filter((a) => a.types?.length).map((a) => [a.id, a.types]))
151
+ const kept = { ...cast, agents: result.agents.map((a) => ({ id: a.id, role: a.role, ...(givenTypes[a.id] ? { types: givenTypes[a.id] } : {}) })), blocks: result.blocks.map((b) => ({ id: b.id, text: b.text })) }
150
152
  const castYaml = writeCast(kept, castText)
151
153
  writeFileSync(castFile, castYaml)
152
154
  console.log(`✓ cast ${castFile}`)