-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoffice-assistant-ingest-meeting.yaml
More file actions
143 lines (137 loc) · 5.13 KB
/
Copy pathoffice-assistant-ingest-meeting.yaml
File metadata and controls
143 lines (137 loc) · 5.13 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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
name: office-assistant-ingest-meeting
description: >
Turn a pasted meeting transcript into structured notes. An LLM writes a summary
and extracts action items; the notes are stored in a Postgres full-text
knowledge base; a single Jira issue is opened for the action items; and the
summary is posted to Teams. Pair with office-assistant-ask.yaml for retrieval.
Requires the schema in office-assistant-kb-schema.sql.
inputs:
title:
type: string
description: Meeting title
meeting_date:
type: string
description: "Meeting date, YYYY-MM-DD (optional)"
default: ""
attendees:
type: string
description: "Comma-separated attendee names (optional)"
default: ""
transcript:
type: string
description: The full meeting transcript — paste it in via a --values file
steps:
# 1. Summarize the transcript and extract structured action items.
- name: summarize
action: ai/completion
credential: openai
timeout: "90s"
params:
model: gpt-4o
system_prompt: >
You are a meeting-notes assistant. From a raw transcript produce: a
concise summary; a list of concrete action items, each with a short
title, a one-line description, and the owner if one was named; a
plain-text rendering of those same action items, one per line as
"Title — description (owner)"; and the key topics discussed. Use only
information present in the transcript.
prompt: >
Meeting: {{ inputs.title }}
Attendees: {{ inputs.attendees }}
Transcript:
{{ inputs.transcript }}
output_schema:
type: object
properties:
summary:
type: string
action_items:
type: array
items:
type: object
properties:
title:
type: string
# description/owner are nullable rather than optional: OpenAI
# strict structured output requires every declared property to
# appear in `required`, so absent values must be expressible as
# null instead of being omitted from the schema.
description:
type:
- string
- "null"
owner:
type:
- string
- "null"
required:
- title
- description
- owner
additionalProperties: false
action_items_text:
type: string
topics:
type: array
items:
type: string
required:
- summary
- action_items
- action_items_text
- topics
additionalProperties: false
# 2. Persist the note into the knowledge base (see office-assistant-kb-schema.sql).
# action_items and topics are stored as JSONB; the search tsvector is
# generated by Postgres from title/summary/transcript.
- name: store-note
action: postgres/query
credential: kb-db
depends_on:
- summarize
timeout: "15s"
params:
# ON CONFLICT makes re-ingesting the same transcript a no-op (dedupe_key
# is md5(transcript)); rows_affected is then 0 and the steps below skip.
query: >
INSERT INTO meeting_notes
(title, meeting_date, attendees, summary, action_items, topics, transcript)
VALUES ($1, NULLIF($2, '')::date, $3, $4, $5::jsonb, $6::jsonb, $7)
ON CONFLICT (dedupe_key) DO NOTHING
args:
- "{{ inputs.title }}"
- "{{ inputs.meeting_date }}"
- "{{ inputs.attendees }}"
- "{{ steps['summarize'].output.json.summary }}"
- "{{ jsonEncode(steps['summarize'].output.json.action_items) }}"
- "{{ jsonEncode(steps['summarize'].output.json.topics) }}"
- "{{ inputs.transcript }}"
# 3. Open one Jira issue capturing the action items (skipped if there are none).
# Per-item fan-out would need a loop construct, which the engine does not
# yet have — a single checklist issue is the clean one-step equivalent.
- name: create-action-items
action: jira/create_issue
credential: jira
depends_on:
- summarize
- store-note
if: "steps['store-note'].output.rows_affected > 0 && size(steps['summarize'].output.json.action_items) > 0"
params:
project_key: OPS
issue_type: Task
summary: "Action items — {{ inputs.title }}"
# jira/create_issue wraps description as a plain-text ADF paragraph, so
# send the plain-text rendering rather than markdown (which would show
# its syntax literally).
description: "{{ steps['summarize'].output.json.action_items_text }}"
# 4. Post the summary to a Teams channel (incoming-webhook credential).
# Skipped on a duplicate re-ingest (store-note inserted no row).
- name: notify-team
action: teams/send_message
credential: teams
depends_on:
- store-note
if: "steps['store-note'].output.rows_affected > 0"
params:
title: "Meeting notes — {{ inputs.title }}"
text: "{{ steps['summarize'].output.json.summary }}"