@deepidealab/n8n-nodes-tracira 0.9.3 → 0.11.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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This is an n8n community node for Tracira.
4
4
 
5
- Tracira monitors AI outputs from your automations, evaluates them against rules, and lets you inspect log results from inside n8n workflows.
5
+ Tracira monitors AI outputs from your automations, evaluates them against rules, and lets you inspect results from inside n8n workflows.
6
6
 
7
7
  [n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/sustainable-use-license/) workflow automation platform.
8
8
 
@@ -31,24 +31,24 @@ The package ships two nodes: **Tracira** (actions) and **Tracira Trigger** (watc
31
31
 
32
32
  ### Tracira Trigger
33
33
 
34
- Starts a workflow the moment a log gets a verdict or a human decision in Tracira. Pick which events to watch - the default (`approved` / `rejected` / `sent back for changes`) fires once a human has decided, the usual choice for approval flows; `flagged`, `passed`, and `error` evaluation events are opt-in. Activating the workflow registers the trigger with Tracira automatically (visible under Integrations → Connected triggers); deactivating removes it. Decision events include the AI `output` and the log `metadata`, so an approval workflow can deliver the approved reply with no extra lookup.
34
+ Starts a workflow the moment an output gets a verdict or a human decision in Tracira. Pick which events to watch - the default (`approved` / `rejected` / `sent back for changes`) fires once a human has decided, the usual choice for approval flows; `flagged`, `passed`, and `error` evaluation events are opt-in. Activating the workflow registers the trigger with Tracira automatically (visible under Integrations → Connected triggers); deactivating removes it. Decision events include the AI `output` and its `metadata`, so an approval workflow can deliver the approved reply with no extra lookup.
35
35
 
36
- The typical human-in-the-loop pattern uses two workflows: workflow A creates the log (AI step → `Create a Log`, Wait for Verdict off), and workflow B starts with the Tracira Trigger, filters on `decision = approved`, and delivers the output.
36
+ The typical human-in-the-loop pattern uses two workflows: workflow A submits the output (AI step → `Check an Output`, Wait for Verdict off), and workflow B starts with the Tracira Trigger, filters on `decision = approved`, and delivers the output.
37
37
 
38
38
  ### Tracira (actions)
39
39
 
40
- The node supports the `Log` resource with these operations (named to match the Tracira Make app modules):
40
+ The node supports the `Output` resource with these operations (named to match the Tracira Make app modules):
41
41
 
42
- - `Create a Log`: Send an AI output to Tracira and create a log for evaluation. Waits for the verdict by default; supports async (fire-and-forget) mode, callback URL with event filtering, and all standard context fields. `Project Name` and `Task Name` offer a searchable dropdown of your existing Tracira projects/tasks, or accept a new name typed manually.
43
- - `Get a Log`: Fetch a single log by ID.
44
- - `Search Logs`: List logs with filters such as status, project, task, and date range.
45
- - `Set a Decision`: `Approve` or `Reject` a flagged log, or `Send Back for Changes` with a comment. The comment is delivered to the downstream automation, which regenerates the output and resubmits it with the `Create a Log` operation's `Revision Of` field set to the original log ID forming a revision chain.
46
- - `Flag a Log`: Flag an evaluated log for human review for example when an end-user reports an issue with an AI response. The log re-enters the pending-review queue and notification channels fire.
47
- - `Upload a File`: Upload a large file (PDF, image, audio) directly to Tracira storage and get back a `key`. Use it for files over ~3 MB that exceed the request size limit; map a binary field (e.g. `data`). Supports up to 32 MB. Pass the returned `key` to the `Create a Log` operation's `Input Attachments` or `Output Attachments` field.
42
+ - `Check an Output`: Send an AI output to Tracira and have it checked against your rules. Waits for the verdict by default; supports async (fire-and-forget) mode, callback URL with event filtering, and all standard context fields. `Project Name` and `Task Name` offer a searchable dropdown of your existing Tracira projects/tasks, or accept a new name typed manually.
43
+ - `Get an Output`: Fetch a single output by ID.
44
+ - `Search Outputs`: List outputs with filters such as status, project, task, and date range.
45
+ - `Set a Decision`: `Approve` or `Reject` a flagged output, or `Send Back for Changes` with a comment. The comment is delivered to the downstream automation, which regenerates the output and resubmits it with the `Check an Output` operation's `Revision Of` field set to the original output ID, forming a revision chain.
46
+ - `Flag an Output`: Flag an already-checked output for human review, for example when an end-user reports an issue with an AI response. The output re-enters the pending-review queue and notification channels fire.
47
+ - `Upload a File`: Upload a large file (PDF, image, audio) directly to Tracira storage and get back a `key`. Use it for files over ~3 MB that exceed the request size limit; map a binary field (e.g. `data`). Supports up to 32 MB. Pass the returned `key` to the `Check an Output` operation's `Input Attachments` or `Output Attachments` field.
48
48
 
49
- The `Create a Log` operation also has `Input Attachments` (files the AI received) and `Output Attachments` (media the AI produced: generated images, synthesized audio, rendered documents) fields, each with three sources: `Upload File` (send a binary field inline with the request — keep under ~3 MB), `From URL` (a publicly accessible HTTPS URL), or `Tracira Upload` (a `key` from the `Upload a File` operation, for large files). `AI Output` text is required unless an `Output Attachment` carries a media-only output.
49
+ The `Check an Output` operation also has `Input Attachments` (files the AI received) and `Output Attachments` (media the AI produced: generated images, synthesized audio, rendered documents) fields, each with three sources: `Upload File` (send a binary field inline with the request — keep under ~3 MB), `From URL` (a publicly accessible HTTPS URL), or `Tracira Upload` (a `key` from the `Upload a File` operation, for large files). `AI Output` text is required unless an `Output Attachment` carries a media-only output.
50
50
 
51
- The `Create a Log` operation's optional `Action (Gate Mode)` field gates a **proposed action** on human review. When your AI decides to run something with side effects (issue a refund, delete a record), fill in the action's `Name`, a plain-language `Summary`, and optional `Parameters (JSON)`. Reviewers approve or reject the action in Tracira before your workflow executes it, and data-field rules can gate it via paths like `action.params.amount`. Combine with a `Callback URL` so the workflow runs the action only after approval.
51
+ The `Check an Output` operation's optional `Action (Gate Mode)` field gates a **proposed action** on human review. When your AI decides to run something with side effects (issue a refund, delete a record), fill in the action's `Name`, a plain-language `Summary`, and optional `Parameters (JSON)`. Reviewers approve or reject the action in Tracira before your workflow executes it, and data-field rules can gate it via paths like `action.params.amount`. Combine with a `Callback URL` so the workflow runs the action only after approval.
52
52
 
53
53
  The node also supports the `API` resource with:
54
54
 
@@ -56,7 +56,7 @@ The node also supports the `API` resource with:
56
56
 
57
57
  ### Sync vs async
58
58
 
59
- By default the `Create a Log` operation **waits for the verdict** (`Wait for Verdict` is on): Tracira evaluates inline and responds with the full `{ ok, id, status, verdict, confidenceScore, explanation }` so you can branch on `status` or `verdict` in the same workflow execution. Evaluation is capped at 30 seconds.
59
+ By default the `Check an Output` operation **waits for the verdict** (`Wait for Verdict` is on): Tracira evaluates inline and responds with the full `{ ok, id, status, verdict, confidenceScore, explanation }` so you can branch on `status` or `verdict` in the same workflow execution. Evaluation is capped at 30 seconds.
60
60
 
61
61
  Turn **Wait for Verdict** off for fire-and-forget logging: Tracira responds immediately with HTTP `202` and `{ ok, id, status: "pending" }`, then evaluates in the background. Use this for high-volume logging where you don't need the verdict inline.
62
62
 
@@ -86,9 +86,9 @@ This package is being set up against the current n8n community-node tooling and
86
86
  Typical pattern:
87
87
 
88
88
  1. Run your AI step in n8n.
89
- 2. Send the model output to `Tracira -> Log -> Create a Log`.
89
+ 2. Send the model output to `Tracira -> Output -> Check an Output`.
90
90
  3. Branch on the returned `status`, `verdict`, or `confidenceScore`.
91
- 4. Optionally query historic logs with `Get a Log` or `Search Logs`.
91
+ 4. Optionally query past outputs with `Get an Output` or `Search Outputs`.
92
92
 
93
93
  ## Example workflow
94
94
 
@@ -97,7 +97,7 @@ An importable example workflow is available at [examples/log-and-branch.workflow
97
97
  The example does this:
98
98
 
99
99
  1. Starts from a manual trigger.
100
- 2. Logs an execution to Tracira.
100
+ 2. Submits an output to Tracira.
101
101
  3. Branches with an `If` node based on the returned `status`.
102
102
 
103
103
  ## Verification notes
@@ -130,11 +130,12 @@ Every node class in this package must follow the conventions that got the existi
130
130
  1. **Codex, twice**: an inline `codex` block in the node description *and* a `<Node>.node.json` file next to the node. The `node` field must be fully qualified (`@deepidealab/n8n-nodes-tracira.<nodeName>`), and the category must be `Analytics` - n8n silently drops the unsupported `AI` category (0.8.1 review finding).
131
131
  2. **Error handling**: wrap HTTP failures in `NodeApiError` so the status code and response body survive into the n8n UI - in `execute()` *and* in trigger `webhookMethods` (attach/detach/checkExists). Bare re-throws were a 0.8.1 review finding; the `require-node-api-error` lint rule also flags bare `throw error` of a catch parameter even when `instanceof`-guarded - use `throw error instanceof NodeOperationError ? error : new NodeApiError(...)`.
132
132
  3. **Icons**: `tracira.svg` + `tracira.dark.svg` copied into the node's own folder (icon paths are relative to the node file).
133
- 4. **`usableAsTool`**: set `true` on action nodes. Trigger nodes cannot be tools and the type forbids `false`, so exempt the `node-usable-as-tool` lint rule with an inline `eslint-disable-next-line` and a comment saying why.
133
+ 4. **`usableAsTool`**: set `true` on every node class, triggers included. Do NOT try to exempt the `node-usable-as-tool` rule with an eslint-disable comment: the verification scanner lints with `allowInlineConfig: false`, so disable comments are ignored and the package fails review (0.9.2 review finding). A trigger is never actually invoked as a tool, so the property is inert there, and the type only permits `true`.
134
134
  5. **Trigger nodes**: name them `<X> Trigger` / `<x>Trigger`, add `activationMessage` and `eventTriggerDescription`, keep the registration id in `getWorkflowStaticData('node')`, and make `checkExists` verify against the API (Tracira auto-prunes dead subscriptions, so a stale local id must re-register).
135
135
  6. **Register the node** in `package.json` → `n8n.nodes` (the `dist/...js` path) - the build does not do this for you.
136
- 7. **Field naming and order**: manager-friendly labels matching the Make custom app ("Input Text", "Input Attachments", "AI Output", "Output Attachments"), ordered as the story of the log: project/task → what the AI received → what it produced → behaviour. Renaming a `displayName` is free; **never rename a parameter `name`** - that breaks existing workflows.
137
- 8. **Verify locally** with `npm run lint` + `npm run build` (needs Node 22+; there is no test script, and `scan-community-package` only works on the published package - CI runs it post-publish).
136
+ 7. **Field naming and order**: manager-friendly labels matching the Make custom app ("Input Text", "Input Attachments", "AI Output", "Output Attachments"), ordered as the story of the output: project/task → what the AI received → what it produced → behaviour. Renaming a `displayName` is free; **never rename a parameter `name`** - that breaks existing workflows.
137
+ 8. **Add a `default`** to every parameter object the scanner can see - including each mode object inside a resourceLocator's `modes` array (`default: ''` on the `list` and `name` modes; 0.9.2 review finding).
138
+ 9. **Verify locally** with `npm run verify` (lint + scanner ESLint + build; needs Node 22+). `npm run scan:source` alone reproduces the verification scanner's ESLint pass against the working tree - `npm run lint` does NOT match it (see PUBLISHING.md). The full published-package scan runs in CI post-publish.
138
139
 
139
140
  ## Releasing a new version
140
141
 
@@ -39,6 +39,21 @@ const apiCallDisplay = {
39
39
  resource: ['api'],
40
40
  operation: ['call'],
41
41
  };
42
+ const instructionsResourceDisplay = {
43
+ resource: ['instructions'],
44
+ };
45
+ const instructionsGetDisplay = {
46
+ resource: ['instructions'],
47
+ operation: ['getInstructions'],
48
+ };
49
+ const instructionsUpdateDisplay = {
50
+ resource: ['instructions'],
51
+ operation: ['updateInstructions'],
52
+ };
53
+ const instructionsAnyDisplay = {
54
+ resource: ['instructions'],
55
+ operation: ['getInstructions', 'updateInstructions'],
56
+ };
42
57
  function stripEmpty(data) {
43
58
  return Object.fromEntries(Object.entries(data).filter(([, value]) => value !== '' && value !== undefined && value !== null));
44
59
  }
@@ -92,7 +107,7 @@ class Tracira {
92
107
  group: ['transform'],
93
108
  version: 1,
94
109
  subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
95
- description: 'Log and inspect Tracira AI log data',
110
+ description: 'Check and inspect your AI outputs in Tracira',
96
111
  usableAsTool: true,
97
112
  codex: {
98
113
  categories: ['Analytics'],
@@ -129,9 +144,13 @@ class Tracira {
129
144
  noDataExpression: true,
130
145
  options: [
131
146
  {
132
- name: 'Log',
147
+ name: 'Output',
133
148
  value: 'log',
134
149
  },
150
+ {
151
+ name: 'Instruction',
152
+ value: 'instructions',
153
+ },
135
154
  {
136
155
  name: 'API',
137
156
  value: 'api',
@@ -149,44 +168,176 @@ class Tracira {
149
168
  },
150
169
  options: [
151
170
  {
152
- name: 'Create a Log',
171
+ name: 'Check an Output',
153
172
  value: 'log',
154
- action: 'Create a log',
155
- description: 'Send an AI output to Tracira and create a log for evaluation. Returns a verdict, confidence score, and explanation based on your configured rules.',
173
+ action: 'Check an output',
174
+ description: 'Send an AI output to Tracira and have it checked against your rules. Returns a verdict, confidence score, and explanation based on your configured rules.',
156
175
  },
157
176
  {
158
- name: 'Flag a Log',
177
+ name: 'Flag an Output',
159
178
  value: 'flag',
160
- action: 'Flag a log',
161
- description: 'Flag an evaluated log for human review, e.g. when an end-user reports an issue',
179
+ action: 'Flag an output',
180
+ description: 'Flag an already-checked output for human review, e.g. when an end-user reports an issue',
162
181
  },
163
182
  {
164
- name: 'Get a Log',
183
+ name: 'Get an Output',
165
184
  value: 'get',
166
- action: 'Get a log',
167
- description: 'Fetch a single log by ID, including verdict, explanation, and human decision',
185
+ action: 'Get an output',
186
+ description: 'Fetch a single output by ID, including verdict, explanation, and human decision',
168
187
  },
169
188
  {
170
- name: 'Search Logs',
189
+ name: 'Search Outputs',
171
190
  value: 'search',
172
- action: 'Search logs',
173
- description: 'Return a filtered list of logs from Tracira. Filter by status, project, task name, or date range.',
191
+ action: 'Search outputs',
192
+ description: 'Return a filtered list of outputs from Tracira. Filter by status, project, task name, or date range.',
174
193
  },
175
194
  {
176
195
  name: 'Set a Decision',
177
196
  value: 'setDecision',
178
197
  action: 'Set a decision',
179
- description: 'Approve, reject, or send a flagged log back to the AI with a comment',
198
+ description: 'Approve, reject, or send a flagged output back to the AI with a comment',
180
199
  },
181
200
  {
182
201
  name: 'Upload a File',
183
202
  value: 'upload',
184
203
  action: 'Upload a file',
185
- description: 'Upload a large file directly to Tracira storage, then attach it to a log by key',
204
+ description: 'Upload a large file directly to Tracira storage, then attach it to an output by key',
186
205
  },
187
206
  ],
188
207
  default: 'log',
189
208
  },
209
+ {
210
+ displayName: 'Operation',
211
+ name: 'operation',
212
+ type: 'options',
213
+ noDataExpression: true,
214
+ displayOptions: {
215
+ show: instructionsResourceDisplay,
216
+ },
217
+ options: [
218
+ {
219
+ name: 'Get Instructions',
220
+ value: 'getInstructions',
221
+ action: 'Get instructions',
222
+ description: 'Fetch the current AI instructions (system prompt) stored in Tracira for a project and task. On the very first run, saves the Starter Instructions as version 1 and returns them.',
223
+ },
224
+ {
225
+ name: 'Update Instructions',
226
+ value: 'updateInstructions',
227
+ action: 'Update instructions',
228
+ description: 'Save a new version of the AI instructions in Tracira and make it active. Use after a reviewer sends a draft back with feedback.',
229
+ },
230
+ ],
231
+ default: 'getInstructions',
232
+ },
233
+ {
234
+ displayName: 'Project Name',
235
+ name: 'instructionsProject',
236
+ type: 'resourceLocator',
237
+ required: true,
238
+ default: { mode: 'list', value: '' },
239
+ displayOptions: {
240
+ show: instructionsAnyDisplay,
241
+ },
242
+ description: 'Must match the Project Name used in the Check an Output operation so the instructions and the outputs belong together',
243
+ modes: [
244
+ {
245
+ displayName: 'From List',
246
+ name: 'list',
247
+ type: 'list',
248
+ default: '',
249
+ typeOptions: {
250
+ searchListMethod: 'getProjects',
251
+ searchable: true,
252
+ },
253
+ },
254
+ {
255
+ displayName: 'Name',
256
+ name: 'name',
257
+ type: 'string',
258
+ default: '',
259
+ },
260
+ ],
261
+ },
262
+ {
263
+ displayName: 'Task Name',
264
+ name: 'instructionsTask',
265
+ type: 'resourceLocator',
266
+ required: true,
267
+ default: { mode: 'list', value: '' },
268
+ displayOptions: {
269
+ show: instructionsAnyDisplay,
270
+ },
271
+ description: 'Must match the Task Name used in the Check an Output operation',
272
+ modes: [
273
+ {
274
+ displayName: 'From List',
275
+ name: 'list',
276
+ type: 'list',
277
+ default: '',
278
+ typeOptions: {
279
+ searchListMethod: 'getTasks',
280
+ searchable: true,
281
+ },
282
+ },
283
+ {
284
+ displayName: 'Name',
285
+ name: 'name',
286
+ type: 'string',
287
+ default: '',
288
+ },
289
+ ],
290
+ },
291
+ {
292
+ displayName: 'Starter Instructions',
293
+ name: 'starterInstructions',
294
+ type: 'string',
295
+ typeOptions: {
296
+ rows: 6,
297
+ },
298
+ default: '',
299
+ displayOptions: {
300
+ show: instructionsGetDisplay,
301
+ },
302
+ description: 'Optional. Used only the very first time this workflow runs: if no instructions exist yet in Tracira for this project and task, this text is saved as version 1 and returned. After that, the instructions stored in Tracira always win.',
303
+ },
304
+ {
305
+ displayName: 'New Instructions',
306
+ name: 'newInstructions',
307
+ type: 'string',
308
+ required: true,
309
+ typeOptions: {
310
+ rows: 6,
311
+ },
312
+ default: '',
313
+ displayOptions: {
314
+ show: instructionsUpdateDisplay,
315
+ },
316
+ description: 'The full updated instructions text. Typically the output of an AI step that rewrote the current instructions to follow the reviewer feedback. This becomes the new active version.',
317
+ },
318
+ {
319
+ displayName: 'Reviewer Feedback',
320
+ name: 'teachComment',
321
+ type: 'string',
322
+ typeOptions: {
323
+ rows: 3,
324
+ },
325
+ default: '',
326
+ displayOptions: {
327
+ show: instructionsUpdateDisplay,
328
+ },
329
+ description: 'Optional. The reviewer comment that caused this update (map the Comment from the Tracira Trigger). Shown in the Tracira dashboard as the reason this version exists.',
330
+ },
331
+ {
332
+ displayName: 'Output ID',
333
+ name: 'instructionsLogId',
334
+ type: 'string',
335
+ default: '',
336
+ displayOptions: {
337
+ show: instructionsUpdateDisplay,
338
+ },
339
+ description: 'Optional. The Tracira output the feedback came from (map the Output ID from the Tracira Trigger).',
340
+ },
190
341
  {
191
342
  displayName: 'Operation',
192
343
  name: 'operation',
@@ -206,7 +357,7 @@ class Tracira {
206
357
  default: 'call',
207
358
  },
208
359
  {
209
- displayName: 'Log ID',
360
+ displayName: 'Output ID',
210
361
  name: 'logId',
211
362
  type: 'string',
212
363
  required: true,
@@ -214,10 +365,10 @@ class Tracira {
214
365
  displayOptions: {
215
366
  show: getDisplay,
216
367
  },
217
- description: 'The log ID to fetch',
368
+ description: 'The output ID to fetch',
218
369
  },
219
370
  {
220
- displayName: 'Log ID',
371
+ displayName: 'Output ID',
221
372
  name: 'decisionLogId',
222
373
  type: 'string',
223
374
  required: true,
@@ -225,7 +376,7 @@ class Tracira {
225
376
  displayOptions: {
226
377
  show: setDecisionDisplay,
227
378
  },
228
- description: 'The log ID to approve or reject',
379
+ description: 'The output ID to approve or reject',
229
380
  },
230
381
  {
231
382
  displayName: 'Decision',
@@ -248,10 +399,10 @@ class Tracira {
248
399
  {
249
400
  name: 'Send Back for Changes',
250
401
  value: 'changed',
251
- description: 'Send the log back to the AI with a comment to regenerate',
402
+ description: 'Send the output back to the AI with a comment to regenerate',
252
403
  },
253
404
  ],
254
- description: 'Approve or reject the flagged log, or send it back to the AI with a comment',
405
+ description: 'Approve or reject the flagged output, or send it back to the AI with a comment',
255
406
  },
256
407
  {
257
408
  displayName: 'Comment',
@@ -268,10 +419,10 @@ class Tracira {
268
419
  decision: ['changed'],
269
420
  },
270
421
  },
271
- description: 'The instruction sent back to the AI describing what to change. Required when Decision is Send Back for Changes. The AI should regenerate the output and resubmit it with the Create a Log operation, setting Revision Of to this log ID.',
422
+ description: 'The instruction sent back to the AI describing what to change. Required when Decision is Send Back for Changes. The AI should regenerate the output and resubmit it with the Check an Output operation, setting Revision Of to this output ID.',
272
423
  },
273
424
  {
274
- displayName: 'Log ID',
425
+ displayName: 'Output ID',
275
426
  name: 'flagLogId',
276
427
  type: 'string',
277
428
  required: true,
@@ -279,7 +430,7 @@ class Tracira {
279
430
  displayOptions: {
280
431
  show: flagDisplay,
281
432
  },
282
- description: 'The log ID to flag for review',
433
+ description: 'The output ID to flag for review',
283
434
  },
284
435
  {
285
436
  displayName: 'Reason',
@@ -292,7 +443,7 @@ class Tracira {
292
443
  displayOptions: {
293
444
  show: flagDisplay,
294
445
  },
295
- description: 'Optional reason for flagging, stored as the log explanation, for example the message your end-user submitted when reporting the issue',
446
+ description: 'Optional reason for flagging, stored as the output explanation, for example the message your end-user submitted when reporting the issue',
296
447
  },
297
448
  {
298
449
  displayName: 'Input Binary Field',
@@ -394,7 +545,7 @@ class Tracira {
394
545
  displayOptions: {
395
546
  show: logOperationDisplay,
396
547
  },
397
- description: "Optional. The text the AI received: the user's message or the prompt. Shown on the person's side of the log.",
548
+ description: "Optional. The text the AI received: the user's message or the prompt. Shown on the person's side of the conversation.",
398
549
  },
399
550
  {
400
551
  displayName: 'Input Attachments',
@@ -511,7 +662,7 @@ class Tracira {
511
662
  displayOptions: {
512
663
  show: logOperationDisplay,
513
664
  },
514
- description: "Files the AI produced: generated images, synthesized audio, or rendered documents. Same options as Input Attachments; shown as the AI's reply in the log.",
665
+ description: "Files the AI produced: generated images, synthesized audio, or rendered documents. Same options as Input Attachments; shown as the AI's reply in the conversation.",
515
666
  options: [
516
667
  {
517
668
  name: 'attachment',
@@ -694,6 +845,13 @@ class Tracira {
694
845
  type: 'number',
695
846
  default: 0,
696
847
  },
848
+ {
849
+ displayName: 'Instructions Version',
850
+ name: 'instructionsVersion',
851
+ type: 'number',
852
+ default: 0,
853
+ description: 'Optional. The Version returned by the Get Instructions operation. The output then links back to the exact instructions the AI ran with, and reviewers can open them from the output.',
854
+ },
697
855
  {
698
856
  displayName: 'Latency',
699
857
  name: 'latencyMs',
@@ -701,12 +859,6 @@ class Tracira {
701
859
  default: 0,
702
860
  description: 'Duration of the AI call in milliseconds',
703
861
  },
704
- {
705
- displayName: 'Log ID',
706
- name: 'id',
707
- type: 'string',
708
- default: '',
709
- },
710
862
  {
711
863
  displayName: 'Metadata JSON',
712
864
  name: 'metadataJson',
@@ -715,14 +867,20 @@ class Tracira {
715
867
  rows: 4,
716
868
  },
717
869
  default: '',
718
- description: 'Optional JSON object to store as log metadata',
870
+ description: 'Optional JSON object to store as output metadata',
871
+ },
872
+ {
873
+ displayName: 'Output ID',
874
+ name: 'id',
875
+ type: 'string',
876
+ default: '',
719
877
  },
720
878
  {
721
879
  displayName: 'Revision Of',
722
880
  name: 'revisionOf',
723
881
  type: 'string',
724
882
  default: '',
725
- description: 'The original log ID when this output is a regeneration triggered by a Changed decision. Tracira links the two as a revision chain so reviewers see every attempt.',
883
+ description: 'The original output ID when this submission is a regeneration triggered by a Changed decision. Tracira links the two as a revision chain so reviewers see every attempt.',
726
884
  },
727
885
  {
728
886
  displayName: 'Session ID',
@@ -741,7 +899,7 @@ class Tracira {
741
899
  name: 'timestamp',
742
900
  type: 'dateTime',
743
901
  default: '',
744
- description: 'Optional. Override the log timestamp useful when replaying or reprocessing past executions. Leave blank to use the current time.',
902
+ description: 'Optional. Override the output timestamp: useful when replaying or reprocessing past executions. Leave blank to use the current time.',
745
903
  },
746
904
  ],
747
905
  },
@@ -760,7 +918,7 @@ class Tracira {
760
918
  { name: 'Pass', value: 'pass' },
761
919
  { name: 'Pending', value: 'pending' },
762
920
  ],
763
- description: 'Filter logs by status',
921
+ description: 'Filter outputs by status',
764
922
  },
765
923
  {
766
924
  displayName: 'Project Name',
@@ -770,7 +928,7 @@ class Tracira {
770
928
  displayOptions: {
771
929
  show: getAllDisplay,
772
930
  },
773
- description: 'Optional. Filter logs to a specific project name.',
931
+ description: 'Optional. Filter outputs to a specific project name.',
774
932
  modes: [
775
933
  {
776
934
  displayName: 'From List',
@@ -798,7 +956,7 @@ class Tracira {
798
956
  displayOptions: {
799
957
  show: getAllDisplay,
800
958
  },
801
- description: 'Optional. Filter logs to a specific task name within a project.',
959
+ description: 'Optional. Filter outputs to a specific task name within a project.',
802
960
  modes: [
803
961
  {
804
962
  displayName: 'From List',
@@ -836,7 +994,7 @@ class Tracira {
836
994
  displayOptions: {
837
995
  show: getAllDisplay,
838
996
  },
839
- description: 'Only include logs at or after this date',
997
+ description: 'Only include outputs at or after this date',
840
998
  },
841
999
  {
842
1000
  displayName: 'To Date',
@@ -846,7 +1004,7 @@ class Tracira {
846
1004
  displayOptions: {
847
1005
  show: getAllDisplay,
848
1006
  },
849
- description: 'Only include logs up to this date',
1007
+ description: 'Only include outputs up to this date',
850
1008
  },
851
1009
  {
852
1010
  displayName: 'Limit',
@@ -1077,6 +1235,7 @@ class Tracira {
1077
1235
  confidence: options.confidence,
1078
1236
  costUsd: options.costUsd,
1079
1237
  id: options.id,
1238
+ instructionsVersion: options.instructionsVersion || undefined,
1080
1239
  revisionOf: options.revisionOf,
1081
1240
  latencyMs: options.latencyMs,
1082
1241
  metadata,
@@ -1087,6 +1246,38 @@ class Tracira {
1087
1246
  }),
1088
1247
  };
1089
1248
  }
1249
+ else if (resource === 'instructions' && operation === 'getInstructions') {
1250
+ requestOptions = {
1251
+ method: 'POST',
1252
+ url: `${baseUrl}/instructions`,
1253
+ body: stripEmpty({
1254
+ project: this.getNodeParameter('instructionsProject', itemIndex, '', {
1255
+ extractValue: true,
1256
+ }),
1257
+ task: this.getNodeParameter('instructionsTask', itemIndex, '', {
1258
+ extractValue: true,
1259
+ }),
1260
+ default: this.getNodeParameter('starterInstructions', itemIndex, ''),
1261
+ }),
1262
+ };
1263
+ }
1264
+ else if (resource === 'instructions' && operation === 'updateInstructions') {
1265
+ requestOptions = {
1266
+ method: 'POST',
1267
+ url: `${baseUrl}/instructions/versions`,
1268
+ body: stripEmpty({
1269
+ project: this.getNodeParameter('instructionsProject', itemIndex, '', {
1270
+ extractValue: true,
1271
+ }),
1272
+ task: this.getNodeParameter('instructionsTask', itemIndex, '', {
1273
+ extractValue: true,
1274
+ }),
1275
+ content: this.getNodeParameter('newInstructions', itemIndex),
1276
+ teachComment: this.getNodeParameter('teachComment', itemIndex, ''),
1277
+ logId: this.getNodeParameter('instructionsLogId', itemIndex, ''),
1278
+ }),
1279
+ };
1280
+ }
1090
1281
  else if (resource === 'log' && operation === 'get') {
1091
1282
  const logId = this.getNodeParameter('logId', itemIndex);
1092
1283
  requestOptions = {