UNPKG

json-object-editor

Version:

JOE the Json Object Editor | Platform Edition

281 lines (267 loc) 15.2 kB
var thought = { display:'Thought', title: 'Thought | ${thought_type}: ${statement}', info: "Persistent reasoning artifact (hypothesis, synthesis, or link) used to build an auditable world model in JOE.", menuicon:`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"> <path d="M418.79 152.21c54.1-4.68 106.11 14.11 145.57 50.7 179.88-61.28 357.82 94.91 322.09 281.77-17.7 92.57-93.99 170.46-185.58 191.53-7.83 1.8-34.03 4.23-38 6.47-2.3 1.29-14.64 18.32-18.65 22.27-82.76 81.43-218.9 67.72-286.83-24.62l-35.16 3.37c-205.89-4.36-263.08-280.1-74.73-364.78 10.05-87.72 83.39-159.08 171.29-166.69Zm-39.41 491.05c4.96 4.51 11.22 16.94 16.69 23.33 46.94 54.84 121.44 70.23 186.17 36.84 26.3-13.56 42.96-35.52 62.34-56.84 75.92-4.51 145.19-42.32 182.22-109.5 88.11-159.86-57.37-346.63-233.69-303.07-9.81 2.43-27.09 11.14-35.93 10.11-8.59-1-28.84-22.68-38.58-29.14-86.51-57.47-207.06-11.17-229.88 89.98-3.02 13.37-1.37 36.64-13.02 43.9-16.07 10.02-32.75 13.56-49.51 26.98-116.69 93.45-38.49 282 110.22 268.53 13.11-1.19 31.88-11.21 42.98-1.12Z"/> <path d="M272.86 721.35c102.07-14 117.43 140.12 22.44 150.52-105.24 11.51-116.96-137.56-22.44-150.52Zm7.15 37.31c-50.22 5.28-41.54 82.79 10.03 75.91 46.11-6.15 39.26-81.09-10.03-75.91Zm164.98-272.61v24.28c0 8.44.36 13.35 1.07 14.73a6.8 6.8 0 0 0 4.63 3.66c3.46.8 7 1.14 10.55 1h6.52c7.08 0 10.62 2.27 10.62 6.82 0 5.26-3.74 8.48-11.22 9.65a209.9 209.9 0 0 1-27.69 1.27c-11.25 0-19.21-2.18-23.89-6.54-4.68-4.36-7.02-11.83-7.04-22.39V488c.32-4.26-.43-8.54-2.19-12.44a14.22 14.22 0 0 0-8.83-5.5 8.79 8.79 0 0 1-6.62-9.26 8.7 8.7 0 0 1 6.62-9.26 14.7 14.7 0 0 0 8.83-5.67 25.36 25.36 0 0 0 2.19-12.44v-30.45c0-10.4 2.34-17.78 7.02-22.14 4.68-4.36 12.64-6.54 23.89-6.52 9.84-.27 19.68.25 29.43 1.57 2.61.4 5.03 1.57 6.97 3.36a8.05 8.05 0 0 1 2.49 5.9c0 4.54-3.54 6.82-10.62 6.82H461c-6.04 0-10.18.65-12.44 1.94a7.7 7.7 0 0 0-3.41 6.72v34.91c-.13 11.76-3.28 19.59-9.45 23.49-.49.33-.77.88-.77 1.47 0 .91 1.1 2.28 3.31 4.11a18.05 18.05 0 0 1 5.18 8.34c1.2 4.27 1.74 8.7 1.59 13.14Zm68.84-76.43a22.82 22.82 0 0 1 22.72 22.72 22.38 22.38 0 0 1-6.92 16.87 23.34 23.34 0 0 1-32.17 0 22.42 22.42 0 0 1-6.92-16.87 21.04 21.04 0 0 1 5.85-15.1 22.79 22.79 0 0 1 17.44-7.61Zm0 56.35a22.82 22.82 0 0 1 22.72 22.72 22.38 22.38 0 0 1-6.94 16.89 23.34 23.34 0 0 1-32.17 0 22.42 22.42 0 0 1-6.92-16.87 21.08 21.08 0 0 1 5.85-15.1 22.78 22.78 0 0 1 17.47-7.64Zm68.15-30.53v-24.18c0-8.44-.36-13.35-1.07-14.73a6.8 6.8 0 0 0-4.63-3.66c-3.46-.8-7-1.14-10.55-1h-6.47c-7.08 0-10.62-2.27-10.62-6.82 0-5.26 3.74-8.44 11.22-9.55a211.64 211.64 0 0 1 27.69-1.27c11.25 0 19.21 2.18 23.89 6.54 4.68 4.36 7.02 11.74 7.02 22.14v30.6c-.33 4.27.42 8.55 2.19 12.44a14.68 14.68 0 0 0 8.83 5.55 8.68 8.68 0 0 1 6.59 9.28 8.7 8.7 0 0 1-4.58 8.38c-1.54.7-3.14 1.26-4.78 1.67a11.2 11.2 0 0 0-7.02 6.54 31.79 31.79 0 0 0-1.27 10.62v30.5c0 10.47-2.34 17.87-7.02 22.22-4.68 4.35-12.64 6.53-23.89 6.54-9.84.28-19.68-.25-29.43-1.57a13.22 13.22 0 0 1-6.97-3.36 8.2 8.2 0 0 1-2.49-6c0-4.54 3.54-6.82 10.62-6.82.85 0 3.09.07 6.72.2 4.24.21 8.47-.45 12.44-1.94a5.76 5.76 0 0 0 2.99-3.96c.5-4.48.68-9 .55-13.51v-24.28c-.19-4.85.52-9.69 2.09-14.28a21.27 21.27 0 0 1 7.46-9.11c.49-.33.77-.88.77-1.47 0-.91-1.1-2.28-3.31-4.11a17.91 17.91 0 0 1-5.18-8.34 43.8 43.8 0 0 1-1.82-13.31Z"/> </svg>`, // Curated summary for agents and tools summary: { description: 'Structured “Thought” records that capture hypotheses, syntheses, and explicit links between JOE objects.', purpose: 'Use thoughts to store inspectable reasoning: hypotheses to be vetted, syntheses that compress many objects, and binary links (A↔B) with receipts. Thoughts are reusable as context in pipelines and agent runs.', labelField: 'name', defaultSort: { field: 'joeUpdated', dir: 'desc' }, searchableFields: ['name', 'statement', 'info', 'thought_type', 'status', 'relationship_type', 'tags', '_id'], allowedSorts: ['joeUpdated', 'created', 'thought_type', 'status', 'certainty'], relationships: { outbound: [ { field: 'tags', targetSchema: 'tag', cardinality: 'many' }, // Polymorphic references: the actual target schema comes from each entry's itemtype/id { field: 'about', targetSchema: '<schemaName>', cardinality: 'many' }, { field: 'because', targetSchema: '<schemaName>', cardinality: 'many' }, { field: 'a', targetSchema: '<schemaName>', cardinality: 'one' }, { field: 'b', targetSchema: '<schemaName>', cardinality: 'one' } ], inbound: { graphRef: 'server/relationships.graph.json' } }, joeManagedFields: ['created', 'joeUpdated'], fields: [ { name: '_id', type: 'string', required: true }, { name: 'itemtype', type: 'string', required: true, const: 'thought' }, { name: 'name', type: 'string', required: true }, { name: 'thought_type', type: 'string', required: true, enumValues: ['hypothesis', 'synthesis', 'link'] }, { name: 'statement', type: 'string', required: true }, { name: 'certainty', type: 'number' }, // Reference to the status object used for this Thought { name: 'status', type: 'string', isReference: true, targetSchema: 'status' }, { name: 'tags', type: 'string', isArray: true, isReference: true, targetSchema: 'tag' }, // Derived field built in onload: array of itemtypes from about[] { name: 'about_itemtypes', type: 'string', isArray: true }, // What this thought is about (objects or schemas) { name: 'about', type: 'objectList' }, // Why we believe the thought (receipts / evidence) { name: 'because', type: 'objectList' }, // Link-specific shape (only used when thought_type === 'link') { name: 'a', type: 'object' }, { name: 'b', type: 'object' }, { name: 'relationship_type', type: 'string' }, { name: 'rationale', type: 'string' }, // Lineage / provenance (ai_response_id, created_by, reviewed_by, etc.) { name: 'source_ai_response', type: 'string', isReference: true, targetSchema: 'ai_response' }, { name: 'created_by', type: 'string' }, { name: 'lineage', type: 'object' }, { name: 'joeUpdated', type: 'string', format: 'date-time', required: true }, { name: 'created', type: 'string', format: 'date-time', required: true } ] }, sorter:['!created','name'], // Simple subsets to quickly slice by type/status subsets: function () { return [ { name: 'Hypotheses', filter: { thought_type: 'hypothesis' } }, { name: 'Syntheses', filter: { thought_type: 'synthesis' } }, { name: 'Links', filter: { thought_type: 'link' } }].concat(_joe.Filter.Options.status({group:'status',collapsed:false})); }, filters: function () { var filters = []; // Tag-based filters are the main cross-cutting dimension for Thoughts filters = filters.concat( _joe.Filter.Options.tags({ group: 'tags', untagged: true, collapsed: true }) ); // Group thoughts by what they are about (about[].itemtype). // We build filters manually so that each itemtype gets its own filter // on the nested path "about.itemtype". JOE's search engine treats this // as "array of objects contains an element whose itemtype matches". try { var dataset = _joe.getDataset('thought') || []; var typeMap = {}; dataset.map(function (t) { if (Array.isArray(t.about)) { t.about.map(function (a) { if (a && a.itemtype) { typeMap[a.itemtype] = true; } }); } }); var types = Object.keys(typeMap).sort(); if (types.length) { filters.push({ group_start: 'about itemtype', collapsed: true }); types.map(function (tp) { filters.push({ name: tp, filter: { 'about.itemtype': tp } }); }); filters.push({ group_end: 'about itemtype' }); } } catch (_e) { /* best-effort only */ } return filters; }, listView: { title: function (th) { var html = `<joe-subtext>${_joe.Utils.prettyPrintDTS(th.created)}</joe-subtext><joe-title>${th.name}</joe-title>`; html += `<joe-subtitle>${th.statement}</joe-subtitle>`; return html; }, listWindowTitle: 'Thoughts' }, // No special stripe color logic for now; could later reflect status/certainty. stripeColor: function () { }, fields: [ { extend: 'name', specs:{ comment: 'Short label for this Thought used in lists and filters.' }}, { name: 'thought_type', type: 'select', values: ['hypothesis', 'synthesis', 'link'], width: '25%' }, //{ name: 'status', type: 'select', values: ['draft', 'proposed', 'accepted', 'rejected', 'superseded'], width: '25%' }, { name: 'certainty', type: 'number', width: '25%', comment: '0–1 confidence score for this thought.' }, { name: 'statement', width: '100%', comment: 'Short, human-readable statement of the thought.' }, { section_start: 'about', display: 'About (what this thought concerns)', anchor:'about', collapsed: false }, { name: 'about', type: 'objectList', properties: [ { name: 'itemtype', type: 'select', width: '140px', values: function () { return (typeof __collectionNames !== 'undefined' && __collectionNames) || []; } }, { name: 'id', width: '220px' }, 'role', 'note' ], comment: 'Objects or schemas this thought is about. Each entry can include an optional role and note.' }, { section_end: 'about' }, { section_start: 'because', display: 'Because (why we believe it)', anchor:'because', collapsed: false }, { name: 'because', type: 'objectList', properties: [ { name: 'itemtype', type: 'select', width: '140px', values: function () { return (typeof __collectionNames !== 'undefined' && __collectionNames) || []; } }, { name: 'id', width: '220px' }, 'role', 'note' ], comment: 'Receipts/evidence supporting this thought. Each entry can include a role (why it matters) and note.' }, { section_end: 'because' }, { section_start: 'link', display: 'Link details (only for link thoughts)', anchor:'link', collapsed: false, hidden: function (item) { return item.thought_type !== 'link'; } }, { name: 'a', type: 'objectList', properties: [ { name: 'itemtype', type: 'select', width: '140px', values: function () { return (typeof __collectionNames !== 'undefined' && __collectionNames) || []; } }, { name: 'id', width: '220px' } ], display: 'Endpoint A', comment: 'First endpoint of the link. Store itemtype and id.', hidden: function (item) { return item.thought_type !== 'link'; } }, { name: 'b', type: 'objectList', properties: [ { name: 'itemtype', type: 'select', width: '140px', values: function () { return (typeof __collectionNames !== 'undefined' && __collectionNames) || []; } }, { name: 'id', width: '220px' } ], display: 'Endpoint B', comment: 'Second endpoint of the link. Store itemtype and id.', hidden: function (item) { return item.thought_type !== 'link'; } }, { name: 'relationship_type', comment: 'Short verb/label for how A relates to B (e.g., included_in, supports, contradicts).', hidden: function (item) { return item.thought_type !== 'link'; } }, { name: 'rationale', comment: 'One-sentence rationale for why this link exists.', hidden: function (item) { return item.thought_type !== 'link'; } }, { section_end: 'link' }, { section_start: 'lineage', display: 'Lineage & provenance', collapsed: true }, { name: 'source_ai_response', type: 'objectReference', values: 'ai_response', display: 'Source AI Response', locked: true }, { name: 'created_by', type: 'string', locked: true }, { name: 'lineage', type: 'rendering', hidden: false, run:function(item){ console.log(item.lineage); return JSON.stringify(item.lineage, null, 2); }, comment: 'Provenance for this thought (ai_response_id, created_by, created_at, reviewed_by, reviewed_at, etc.).' }, { section_end: 'lineage' }, { sidebar_start:'right'}, 'status', 'tags', { sidebar_end:'right'}, { section_start: 'system', collapsed: true }, '_id', 'created', 'itemtype', { section_end: 'system' } ], // Populate derived helper fields on load onload: function (dataset) { if (!Array.isArray(dataset)) { return; } dataset.map(function (t) { if (Array.isArray(t.about)) { var types = t.about.map(function (a) { return a && a.itemtype; }).filter(Boolean); // Deduplicate t.about_itemtypes = Array.from(new Set(types)); } }); }, idprop: '_id' }; module.exports = thought;