fuli-context 0.7.3 → 0.7.4-beta.1
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 +170 -18
- package/README.zh-CN.md +146 -12
- package/compose.graphiti.yml +2 -0
- package/dist/web/assets/{AboutPage-qeO_vm0T.js → AboutPage-CftRexSY.js} +1 -1
- package/dist/web/assets/{ConnectionsPage-DO0GR9Xg.js → ConnectionsPage-D5J91x6d.js} +1 -1
- package/dist/web/assets/{useMinimumLoadingDisplay-BpCyBeko.css → KnowledgeEditDialog-DWUV_NPp.css} +1 -1
- package/dist/web/assets/KnowledgeEditDialog-wotVahvr.js +1 -0
- package/dist/web/assets/{KnowledgeInspector-Bjhdu2mf.css → KnowledgeInspector--1NujtXW.css} +1 -1
- package/dist/web/assets/KnowledgeInspector-BzkW0mVs.js +1 -0
- package/dist/web/assets/KnowledgeOrganizerPage-BebUDiHt.js +1 -0
- package/dist/web/assets/KnowledgePage-OUT07aKH.js +1 -0
- package/dist/web/assets/KnowledgeWorkspace-1pHJ0MNZ.js +4 -0
- package/dist/web/assets/{OverviewPage-CmCcDCAs.js → OverviewPage-CHE6XhdS.js} +1 -1
- package/dist/web/assets/PersonalProfilePage-B7T09bow.css +1 -0
- package/dist/web/assets/PersonalProfilePage-CXXiabUy.js +1 -0
- package/dist/web/assets/PersonalProjectsPage-d2wYGW8n.js +1 -0
- package/dist/web/assets/PublicProjectsPage-hxLShtnZ.js +1 -0
- package/dist/web/assets/{ReviewPage-B3vnZ6gn.js → ReviewPage-DUeyu7E8.js} +1 -1
- package/dist/web/assets/{SearchableSelect-ih69qbcS.js → SearchableSelect-C5RiB5F8.js} +1 -1
- package/dist/web/assets/SettingsPage-BMuASSzQ.js +1 -0
- package/dist/web/assets/SettingsPage-CAfz4qiV.css +1 -0
- package/dist/web/assets/WritingTastePage-B9BCYIwQ.js +1 -0
- package/dist/web/assets/WritingTastePage-DSgvTH6x.css +1 -0
- package/dist/web/assets/{console-DE40hXGC.js → console-DMvHxKf9.js} +1 -1
- package/dist/web/assets/conversation-launcher-settings-Dnlcw7Rj.js +1 -0
- package/dist/web/assets/{i18n-CDxBs1sz.js → i18n-CWfd8Dtt.js} +1 -1
- package/dist/web/assets/{identity-BCxb1mcy.js → identity-C9mLdR8L.js} +1 -1
- package/dist/web/assets/index-F5e2sQ7p.js +2 -0
- package/dist/web/assets/{index-CCOGfZzE.css → index-X2j29j8i.css} +1 -1
- package/dist/web/assets/{model-CCMdt10Q.js → model-CsYAR8O3.js} +1 -1
- package/dist/web/assets/paths-CDREouhi.js +1 -0
- package/dist/web/assets/useApi-CROJJdhE-BLQiPVw0.js +1 -0
- package/dist/web/assets/vue-router-DN8x6iY1.js +1 -0
- package/dist/web/index.html +7 -6
- package/graph-provider/fuli_graph/app.py +238 -2
- package/graph-provider/fuli_graph/auth.py +18 -0
- package/graph-provider/fuli_graph/collaboration_context.py +253 -17
- package/graph-provider/fuli_graph/common_knowledge.py +6 -2
- package/graph-provider/fuli_graph/config.py +5 -0
- package/graph-provider/fuli_graph/graph_models.py +6 -0
- package/graph-provider/fuli_graph/graph_projection.py +14 -0
- package/graph-provider/fuli_graph/graph_query.py +27 -3
- package/graph-provider/fuli_graph/knowledge_management.py +19 -1
- package/graph-provider/fuli_graph/knowledge_search.py +11 -0
- package/graph-provider/fuli_graph/models.py +15 -2
- package/graph-provider/fuli_graph/personal_global_preference_models.py +234 -0
- package/graph-provider/fuli_graph/personal_global_preferences.py +1247 -0
- package/graph-provider/fuli_graph/project_action_models.py +22 -0
- package/graph-provider/fuli_graph/project_knowledge.py +121 -2
- package/graph-provider/fuli_graph/provider_values.py +24 -0
- package/graph-provider/fuli_graph/runtime.py +78 -0
- package/graph-provider/fuli_graph/search_projection.py +14 -1
- package/graph-provider/fuli_graph/store_knowledge.py +116 -2
- package/graph-provider/fuli_graph/workflow_candidate_models.py +168 -0
- package/graph-provider/fuli_graph/workflow_candidates.py +996 -0
- package/graph-provider/fuli_graph/workflow_observation_models.py +30 -0
- package/graph-provider/fuli_graph/workflow_observations.py +84 -0
- package/graph-provider/pyproject.toml +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +4 -4
- package/skills/capturing-session-knowledge/SKILL.md +32 -5
- package/skills/flreview/SKILL.md +4 -3
- package/src/agent-tools/graph-definitions.js +136 -20
- package/src/agent-tools/graph-handlers.js +10 -4
- package/src/cli/command-registry.js +1 -1
- package/src/cli/local-runtime-command.js +69 -2
- package/src/graphiti/agent-knowledge-workflows.js +497 -16
- package/src/graphiti/collaboration-preference-projection.js +162 -0
- package/src/graphiti/federated-application.js +155 -161
- package/src/graphiti/federated-search-support.js +102 -0
- package/src/graphiti/knowledge-provider-mapping.js +15 -0
- package/src/graphiti/provider-client.js +162 -10
- package/src/graphiti/related-project-suggestions.js +109 -0
- package/src/graphiti/runtime-config.js +14 -0
- package/src/graphiti/source-marker.js +2 -2
- package/src/graphiti/user-taste-skill.js +241 -0
- package/src/graphiti/workflow-candidate-mapping.js +87 -0
- package/src/graphiti/workflow-observation.js +82 -0
- package/src/graphiti/writing-taste-profile-workflow.js +25 -0
- package/src/graphiti/writing-taste-profile.js +490 -0
- package/src/http/graph-api-router.js +15 -2
- package/src/mcp/context-resources.js +158 -0
- package/src/mcp/create-mcp-server.js +39 -5
- package/src/mcp/instructions.js +5 -7
- package/src/mcp/session-id.js +60 -0
- package/src/mcp/task-context-registry.js +15 -3
- package/src/mcp/tool-annotations.js +8 -1
- package/src/mcp/tool-result.js +28 -4
- package/src/server.js +0 -1
- package/src/setup/claude-code-config.js +17 -6
- package/src/setup/graph-runtime.js +20 -2
- package/src/system/runtime-settings.js +121 -2
- package/src/system/system-service.js +5 -1
- package/dist/web/assets/KnowledgeInspector-DEW5lA1m.js +0 -1
- package/dist/web/assets/KnowledgeOrganizerPage-BkM568Ld.js +0 -1
- package/dist/web/assets/KnowledgePage-BAT4aZIm.js +0 -1
- package/dist/web/assets/KnowledgeWorkspace-DyGtBz--.js +0 -4
- package/dist/web/assets/PersonalProfilePage-C42mwKN8.js +0 -1
- package/dist/web/assets/PersonalProfilePage-CdmEzyvZ.css +0 -1
- package/dist/web/assets/PersonalProjectsPage-BwaXR62K.js +0 -1
- package/dist/web/assets/PublicProjectsPage-egKBulOq.js +0 -1
- package/dist/web/assets/SettingsPage-C6ouU0sR.css +0 -1
- package/dist/web/assets/SettingsPage-oLE8mNs5.js +0 -1
- package/dist/web/assets/index-BzhNfzU_.js +0 -2
- package/dist/web/assets/paths-DwHeiGMT.js +0 -1
- package/dist/web/assets/useMinimumLoadingDisplay-HdI7XAmu.js +0 -1
- package/dist/web/assets/vue-router-Drfl1F8i.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,E as t,F as n,G as r,J as i,Q as a,S as o,Y as s,p as c,q as l,w as u,x as d}from"./i18n-CWfd8Dtt.js";import{a as f,c as p,d as m,f as h,g,i as _,l as v,n as y,o as b,p as ee,r as x,s as S,t as C,u as w}from"./useApi-CROJJdhE-BLQiPVw0.js";var T=typeof document<`u`,E=/#/g,te=/&/g,ne=/\//g,re=/=/g,D=/\?/g,O=/\+/g,ie=/%5B/g,k=/%5D/g,ae=/%5E/g,oe=/%60/g,A=/%7B/g,se=/%7C/g,j=/%7D/g,M=/%20/g;function N(e){return e==null?``:encodeURI(``+e).replace(se,`|`).replace(ie,`[`).replace(k,`]`)}function ce(e){return N(e).replace(A,`{`).replace(j,`}`).replace(ae,`^`)}function P(e){return N(e).replace(O,`%2B`).replace(M,`+`).replace(E,`%23`).replace(te,`%26`).replace(oe,"`").replace(A,`{`).replace(j,`}`).replace(ae,`^`)}function F(e){return P(e).replace(re,`%3D`)}function le(e){return N(e).replace(E,`%23`).replace(D,`%3F`)}function ue(e){return le(e).replace(ne,`%2F`)}function I(e){if(e==null)return null;try{return decodeURIComponent(``+e)}catch{}return``+e}var L=/\/$/,R=e=>e.replace(L,``);function z(e,t,n=`/`){let r,i={},a=``,o=``,s=t.indexOf(`#`),c=t.indexOf(`?`);return c=s>=0&&c>s?-1:c,c>=0&&(r=t.slice(0,c),a=t.slice(c,s>0?s:t.length),i=e(a.slice(1))),s>=0&&(r||=t.slice(0,s),o=t.slice(s,t.length)),r=G(r??t,n),{fullPath:r+a+o,path:r,query:i,hash:I(o)}}function de(e,t){let n=t.query?e(t.query):``;return t.path+(n&&`?`)+n+(t.hash||``)}function B(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||`/`}function fe(e,t,n){let r=t.matched.length-1,i=n.matched.length-1;return r>-1&&r===i&&V(t.matched[r],n.matched[i])&&H(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function V(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function H(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!U(e[n],t[n]))return!1;return!0}function U(e,t){return _(e)?W(e,t):_(t)?W(t,e):(e&&e.valueOf())===(t&&t.valueOf())}function W(e,t){return _(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e.length===1&&e[0]===t}function G(e,t){if(e.startsWith(`/`))return e;if(!e)return t;let n=t.split(`/`),r=e.split(`/`),i=r[r.length-1];(i===`..`||i===`.`)&&r.push(``);let a=n.length-1,o,s;for(o=0;o<r.length;o++)if(s=r[o],s!==`.`)if(s===`..`)a>1&&a--;else break;return n.slice(0,a).join(`/`)+`/`+r.slice(o).join(`/`)}var K={path:`/`,name:void 0,params:{},query:{},hash:``,fullPath:`/`,matched:[],meta:{},redirectedFrom:void 0};function q(e){if(!e)if(T){let t=document.querySelector(`base`);e=t&&t.getAttribute(`href`)||`/`,e=e.replace(/^\w+:\/\/[^/]+/,``)}else e=`/`;return e[0]!==`/`&&e[0]!==`#`&&(e=`/`+e),R(e)}var J=/^[^#]+#/;function Y(e,t){return e.replace(J,`#`)+t}function X(e,t){let n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}var Z=()=>({left:window.scrollX,top:window.scrollY});function pe(e){let t;if(`el`in e){let n=e.el,r=typeof n==`string`&&n.startsWith(`#`),i=typeof n==`string`?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!i)return;t=X(i,e)}else t=e;`scrollBehavior`in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left==null?window.scrollX:t.left,t.top==null?window.scrollY:t.top)}function me(e,t){return(history.state?history.state.position-t:-1)+e}var he=new Map;function ge(e,t){he.set(e,t)}function _e(e){let t=he.get(e);return he.delete(e),t}function ve(e){return typeof e==`string`||e&&typeof e==`object`}function ye(e){return typeof e==`string`||typeof e==`symbol`}function be(e){let t={};if(e===``||e===`?`)return t;let n=(e[0]===`?`?e.slice(1):e).split(`&`);for(let e=0;e<n.length;++e){let r=n[e].replace(O,` `),i=r.indexOf(`=`),a=I(i<0?r:r.slice(0,i)),o=i<0?null:I(r.slice(i+1));if(a in t){let e=t[a];_(e)||(e=t[a]=[e]),e.push(o)}else t[a]=o}return t}function xe(e){let t=``;for(let n in e){let r=e[n];if(n=F(n),r==null){r!==void 0&&(t+=(t.length?`&`:``)+n);continue}(_(r)?r.map(e=>e&&P(e)):[r&&P(r)]).forEach(e=>{e!==void 0&&(t+=(t.length?`&`:``)+n,e!=null&&(t+=`=`+e))})}return t}function Se(e){let t={};for(let n in e){let r=e[n];r!==void 0&&(t[n]=_(r)?r.map(e=>e==null?null:``+e):r==null?r:``+r)}return t}function Q(){let e=[];function t(t){return e.push(t),()=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function $(e,t,n,r,i,a=e=>e()){let o=r&&(r.enterCallbacks[i]=r.enterCallbacks[i]||[]);return()=>new Promise((s,c)=>{let l=e=>{e===!1?c(x(4,{from:n,to:t})):e instanceof Error?c(e):ve(e)?c(x(2,{from:t,to:e})):(o&&r.enterCallbacks[i]===o&&typeof e==`function`&&o.push(e),s())},u=a(()=>e.call(r&&r.instances[i],t,n,l)),d=Promise.resolve(u);e.length<3&&(d=d.then(l)),d.catch(e=>c(e))})}function Ce(e,t,n,r,i=e=>e()){let a=[];for(let o of e)for(let e in o.components){let s=o.components[e];if(!(t!==`beforeRouteEnter`&&!o.instances[e]))if(S(s)){let c=(s.__vccOpts||s)[t];c&&a.push($(c,n,r,o,e,i))}else{let c=s();a.push(()=>c.then(a=>{if(!a)throw Error(`Couldn't resolve component "${e}" at "${o.path}"`);let s=f(a)?a.default:a;o.mods[e]=a,o.components[e]=s;let c=(s.__vccOpts||s)[t];return c&&$(c,n,r,o,e,i)()}))}}return a}function we(e,t){let n=[],r=[],i=[],a=Math.max(t.matched.length,e.matched.length);for(let o=0;o<a;o++){let a=t.matched[o];a&&(e.matched.find(e=>V(e,a))?r.push(a):n.push(a));let s=e.matched[o];s&&(t.matched.find(e=>V(e,s))||i.push(s))}return[n,r,i]}var Te=()=>location.protocol+`//`+location.host;function Ee(e,t){let{pathname:n,search:r,hash:i}=t,a=e.indexOf(`#`);if(a>-1){let t=i.includes(e.slice(a))?e.slice(a).length:1,n=i.slice(t);return n[0]!==`/`&&(n=`/`+n),B(n,``)}return B(n,e)+r+i}function De(e,t,n,r){let i=[],a=[],o=null,s=({state:a})=>{let s=Ee(e,location),c=n.value,l=t.value,u=0;if(a){if(n.value=s,t.value=a,o&&o===c){o=null;return}u=l?a.position-l.position:0}else r(s);i.forEach(e=>{e(n.value,c,{delta:u,type:`pop`,direction:u?u>0?`forward`:`back`:``})})};function c(){o=n.value}function l(e){i.push(e);let t=()=>{let t=i.indexOf(e);t>-1&&i.splice(t,1)};return a.push(t),t}function u(){if(document.visibilityState===`hidden`){let{history:e}=window;if(!e.state)return;e.replaceState(y({},e.state,{scroll:Z()}),``)}}function d(){for(let e of a)e();a=[],window.removeEventListener(`popstate`,s),window.removeEventListener(`pagehide`,u),document.removeEventListener(`visibilitychange`,u)}return window.addEventListener(`popstate`,s),window.addEventListener(`pagehide`,u),document.addEventListener(`visibilitychange`,u),{pauseListeners:c,listen:l,destroy:d}}function Oe(e,t,n,r=!1,i=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:i?Z():null}}function ke(e){let{history:t,location:n}=window,r={value:Ee(e,n)},i={value:t.state};i.value||a(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function a(r,a,o){let s=e.indexOf(`#`),c=s>-1?(n.host&&document.querySelector(`base`)?e:e.slice(s))+r:Te()+e+r;try{t[o?`replaceState`:`pushState`](a,``,c),i.value=a}catch(e){console.error(e),n[o?`replace`:`assign`](c)}}function o(e,n){a(e,y({},t.state,Oe(i.value.back,e,i.value.forward,!0),n,{position:i.value.position}),!0),r.value=e}function s(e,n){let o=y({},i.value,t.state,{forward:e,scroll:Z()});a(o.current,o,!0),a(e,y({},Oe(r.value,e,null),{position:o.position+1},n),!1),r.value=e}return{location:r,state:i,push:s,replace:o}}function Ae(e){e=q(e);let t=ke(e),n=De(e,t.state,t.location,t.replace);function r(e,t=!0){t||n.pauseListeners(),history.go(e)}let i=y({location:``,base:e,go:r,createHref:Y.bind(null,e)},t,n);return Object.defineProperty(i,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(i,"state",{enumerable:!0,get:()=>t.state.value}),i}var je={type:0,value:``},Me=/[a-zA-Z0-9_]/;function Ne(e){if(!e)return[[]];if(e===`/`)return[[je]];if(!e.startsWith(`/`))throw Error(`Invalid path "${e}"`);function t(e){throw Error(`ERR (${n})/"${l}": ${e}`)}let n=0,r=n,i=[],a;function o(){a&&i.push(a),a=[]}let s=0,c,l=``,u=``;function d(){l&&=(n===0?a.push({type:0,value:l}):n===1||n===2||n===3?(a.length>1&&(c===`*`||c===`+`)&&t(`A repeatable param (${l}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:l,regexp:u,repeatable:c===`*`||c===`+`,optional:c===`*`||c===`?`})):t(`Invalid state to consume buffer`),``)}function f(){l+=c}for(;s<e.length;)switch(c=e[s++],n){case 0:c===`\\`?(r=n,n=4):c===`/`?(l&&d(),o()):c===`:`?(d(),n=1):f();break;case 4:f(),n=r;break;case 1:c===`(`?n=2:Me.test(c)?f():(d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--);break;case 2:c===`)`?u[u.length-1]==`\\`?u=u.slice(0,-1)+c:n=3:u+=c;break;case 3:d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--,u=``;break;default:t(`Unknown state`);break}return n===2&&t(`Unfinished custom RegExp for param "${l}"`),d(),o(),i}var Pe=`[^/]+?`,Fe={sensitive:!1,strict:!1,start:!0,end:!0},Ie=/[.+*?^${}()[\]/\\]/g;function Le(e,t){let n=y({},Fe,t),r=[],i=n.start?`^`:``,a=[];for(let t of e){let e=t.length?[]:[90];n.strict&&!t.length&&(i+=`/`);for(let r=0;r<t.length;r++){let o=t[r],s=40+(n.sensitive?.25:0);if(o.type===0)r||(i+=`/`),i+=o.value.replace(Ie,`\\$&`),s+=40;else if(o.type===1){let{value:e,repeatable:n,optional:c,regexp:l}=o;a.push({name:e,repeatable:n,optional:c});let u=l||Pe;if(u!==Pe){s+=10;try{RegExp(`(${u})`)}catch(t){throw Error(`Invalid custom RegExp for param "${e}" (${u}): `+t.message)}}let d=n?`((?:${u})(?:/(?:${u}))*)`:`(${u})`;r||(d=c&&t.length<2?`(?:/${d})`:`/`+d),c&&(d+=`?`),i+=d,s+=20,c&&(s+=-8),n&&(s+=-20),u===`.*`&&(s+=-50)}e.push(s)}r.push(e)}if(n.strict&&n.end){let e=r.length-1;r[e][r[e].length-1]+=.7000000000000001}n.strict||(i+=`/?`),n.end?i+=`$`:n.strict&&!i.endsWith(`/`)&&(i+=`(?:/|$)`);let o=new RegExp(i,n.sensitive?``:`i`);function s(e){let t=e.match(o),n={};if(!t)return null;for(let e=1;e<t.length;e++){let r=t[e]||``,i=a[e-1];n[i.name]=r&&i.repeatable?r.split(`/`):r}return n}function c(t){let n=``,r=!1;for(let i of e){(!r||!n.endsWith(`/`))&&(n+=`/`),r=!1;for(let e of i)if(e.type===0)n+=e.value;else if(e.type===1){let{value:a,repeatable:o,optional:s}=e,c=a in t?t[a]:``;if(_(c)&&!o)throw Error(`Provided param "${a}" is an array but it is not repeatable (* or + modifiers)`);let l=_(c)?c.join(`/`):c;if(!l)if(s)i.length<2&&(n.endsWith(`/`)?n=n.slice(0,-1):r=!0);else throw Error(`Missing required param "${a}"`);n+=l}}return n||`/`}return{re:o,score:r,keys:a,parse:s,stringify:c}}function Re(e,t){let n=0;for(;n<e.length&&n<t.length;){let r=t[n]-e[n];if(r)return r;n++}return e.length<t.length?e.length===1&&e[0]===80?-1:1:e.length>t.length?t.length===1&&t[0]===80?1:-1:0}function ze(e,t){let n=0,r=e.score,i=t.score;for(;n<r.length&&n<i.length;){let e=Re(r[n],i[n]);if(e)return e;n++}if(Math.abs(i.length-r.length)===1){if(Be(r))return 1;if(Be(i))return-1}return i.length-r.length}function Be(e){let t=e[e.length-1];return e.length>0&&t[t.length-1]<0}var Ve={strict:!1,end:!0,sensitive:!1};function He(e,t,n){let r=y(Le(Ne(e.path),n),{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function Ue(e,t){let n=[],r=new Map;t=v(Ve,t);function i(e){return r.get(e)}function a(e,n,r){let i=!r,s=Ge(e);s.aliasOf=r&&r.record;let l=v(t,e),u=[s];if(`alias`in e){let t=typeof e.alias==`string`?[e.alias]:e.alias;for(let e of t)u.push(Ge(y({},s,{components:r?r.record.components:s.components,path:e,aliasOf:r?r.record:s})))}let d,f;for(let t of u){let{path:u}=t;if(n&&u[0]!==`/`){let e=n.record.path,r=e[e.length-1]===`/`?``:`/`;t.path=n.record.path+(u&&r+u)}if(d=He(t,n,l),r?r.alias.push(d):(f||=d,f!==d&&f.alias.push(d),i&&e.name&&!qe(d)&&o(e.name)),Ze(d)&&c(d),s.children){let e=s.children;for(let t=0;t<e.length;t++)a(e[t],d,r&&r.children[t])}r||=d}return f?()=>{o(f)}:w}function o(e){if(ye(e)){let t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(o),t.alias.forEach(o))}else{let t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(o),e.alias.forEach(o))}}function s(){return n}function c(e){let t=Ye(e,n);n.splice(t,0,e),e.record.name&&!qe(e)&&r.set(e.record.name,e)}function l(e,t){let i,a={},o,s;if(`name`in e&&e.name){if(i=r.get(e.name),!i)throw x(1,{location:e});s=i.record.name,a=y(We(t.params,i.keys.filter(e=>!e.optional).concat(i.parent?i.parent.keys.filter(e=>e.optional):[]).map(e=>e.name)),e.params&&We(e.params,i.keys.map(e=>e.name))),o=i.stringify(a)}else if(e.path!=null)o=e.path,i=n.find(e=>e.re.test(o)),i&&(a=i.parse(o),s=i.record.name,i.keys.forEach(e=>{e.optional&&!a[e.name]&&delete a[e.name]}));else{if(i=t.name?r.get(t.name):n.find(e=>e.re.test(t.path)),!i)throw x(1,{location:e,currentLocation:t});s=i.record.name,a=y({},t.params,e.params),o=i.stringify(a)}let c=[],l=i;for(;l;)c.unshift(l.record),l=l.parent;return{name:s,path:o,params:a,matched:c,meta:Je(c)}}e.forEach(e=>a(e));function u(){n.length=0,r.clear()}return{addRoute:a,resolve:l,removeRoute:o,clearRoutes:u,getRoutes:s,getRecordMatcher:i}}function We(e,t){let n={};for(let r of t)r in e&&(n[r]=e[r]);return n}function Ge(e){let t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Ke(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:`components`in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Ke(e){let t={},n=e.props||!1;if(`component`in e)t.default=n;else for(let r in e.components)t[r]=typeof n==`object`?n[r]:n;return t}function qe(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Je(e){return e.reduce((e,t)=>y(e,t.meta),{})}function Ye(e,t){let n=0,r=t.length;for(;n!==r;){let i=n+r>>1;ze(e,t[i])<0?r=i:n=i+1}let i=Xe(e);return i&&(r=t.lastIndexOf(i,r-1)),r}function Xe(e){let t=e;for(;t=t.parent;)if(Ze(t)&&ze(e,t)===0)return t}function Ze({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Qe(e){let t=u(h),n=u(m),r=c(()=>{let n=a(e.to);return t.resolve(n)}),i=c(()=>{let{matched:e}=r.value,{length:t}=e,i=e[t-1],a=n.matched;if(!i||!a.length)return-1;let o=a.findIndex(V.bind(null,i));if(o>-1)return o;let s=rt(e[t-2]);return t>1&&rt(i)===s&&a[a.length-1].path!==s?a.findIndex(V.bind(null,e[t-2])):o}),o=c(()=>i.value>-1&&nt(n.params,r.value.params)),s=c(()=>i.value>-1&&i.value===n.matched.length-1&&H(n.params,r.value.params));function l(n={}){if(tt(n)){let n=t[a(e.replace)?`replace`:`push`](a(e.to)).catch(w);return e.viewTransition&&typeof document<`u`&&`startViewTransition`in document&&document.startViewTransition(()=>n),n}return Promise.resolve()}return{route:r,href:c(()=>r.value.href),isActive:o,isExactActive:s,navigate:l}}function $e(e){return e.length===1?e[0]:e}var et=d({name:`RouterLink`,compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:`page`},viewTransition:Boolean},useLink:Qe,setup(e,{slots:t}){let n=r(Qe(e)),{options:i}=u(h),a=c(()=>({[it(e.activeClass,i.linkActiveClass,`router-link-active`)]:n.isActive,[it(e.exactActiveClass,i.linkExactActiveClass,`router-link-exact-active`)]:n.isExactActive}));return()=>{let r=t.default&&$e(t.default(n));return e.custom?r:o(`a`,{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:a.value},r)}}});function tt(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){let t=e.currentTarget.getAttribute(`target`);if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function nt(e,t){for(let n in t){let r=t[n],i=e[n];if(typeof r==`string`){if(r!==i)return!1}else if(!_(i)||i.length!==r.length||r.some((e,t)=>e.valueOf()!==i[t].valueOf()))return!1}return!0}function rt(e){return e?e.aliasOf?e.aliasOf.path:e.path:``}var it=(e,t,n)=>e??t??n,at=d({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(t,{attrs:r,slots:i}){let s=u(ee),d=c(()=>t.route||s.value),f=u(g,0),m=c(()=>{let e=a(f),{matched:t}=d.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),h=c(()=>d.value.matched[m.value]);e(g,c(()=>m.value+1)),e(p,h),e(ee,d);let _=l();return n(()=>[_.value,h.value,t.name],([e,t,n],[r,i,a])=>{t&&(t.instances[n]=e,i&&i!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=i.leaveGuards),t.updateGuards.size||(t.updateGuards=i.updateGuards))),e&&t&&(!i||!V(t,i)||!r)&&(t.enterCallbacks[n]||[]).forEach(t=>t(e))},{flush:`post`}),()=>{let e=d.value,n=t.name,a=h.value,s=a&&a.components[n];if(!s)return ot(i.default,{Component:s,route:e});let c=a.props[n],l=o(s,y({},c?c===!0?e.params:typeof c==`function`?c(e):c:null,r,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(a.instances[n]=null)},ref:_}));return ot(i.default,{Component:l,route:e})||l}}});function ot(e,t){if(!e)return null;let n=e(t);return n.length===1?n[0]:n}var st=at;function ct(e){let n=Ue(e.routes,e),r=e.parseQuery||be,o=e.stringifyQuery||xe,c=e.history,l=Q(),u=Q(),d=Q(),f=s(K),p=K;T&&e.scrollBehavior&&`scrollRestoration`in history&&(history.scrollRestoration=`manual`);let g=C.bind(null,e=>``+e),v=C.bind(null,ue),S=C.bind(null,I);function E(e,t){let r,i;return ye(e)?(r=n.getRecordMatcher(e),i=t):i=e,n.addRoute(i,r)}function te(e){let t=n.getRecordMatcher(e);t&&n.removeRoute(t)}function ne(){return n.getRoutes().map(e=>e.record)}function re(e){return!!n.getRecordMatcher(e)}function D(e,t){if(t=y({},t||f.value),typeof e==`string`){let i=z(r,e,t.path),a=n.resolve({path:i.path},t),o=c.createHref(i.fullPath);return y(i,a,{params:S(a.params),redirectedFrom:void 0,href:o})}let i;if(e.path!=null)i=y({},e,{path:z(r,e.path,t.path).path});else{let n=y({},e.params);for(let e in n)n[e]??delete n[e];i=y({},e,{params:v(n)}),t.params=v(t.params)}let a=n.resolve(i,t),s=e.hash||``;a.params=g(S(a.params));let l=de(o,y({},e,{hash:ce(s),path:a.path})),u=c.createHref(l);return y({fullPath:l,hash:s,query:o===xe?Se(e.query):e.query||{}},a,{redirectedFrom:void 0,href:u})}function O(e){return typeof e==`string`?z(r,e,f.value.path):y({},e)}function ie(e,t){if(p!==e)return x(8,{from:t,to:e})}function k(e){return A(e)}function ae(e){return k(y(O(e),{replace:!0}))}function oe(e,t){let n=e.matched[e.matched.length-1];if(n&&n.redirect){let{redirect:r}=n,i=typeof r==`function`?r(e,t):r;return typeof i==`string`&&(i=i.includes(`?`)||i.includes(`#`)?i=O(i):{path:i},i.params={}),y({query:e.query,hash:e.hash,params:i.path==null?e.params:{}},i)}}function A(e,t){let n=p=D(e),r=f.value,i=e.state,a=e.force,s=e.replace===!0,c=oe(n,r);if(c)return A(y(O(c),{state:typeof c==`object`?y({},i,c.state):i,force:a,replace:s}),t||n);let l=n;l.redirectedFrom=t;let u;return!a&&fe(o,r,n)&&(u=x(16,{to:l,from:r}),W(r,r,!0,!1)),(u?Promise.resolve(u):M(l,r)).catch(e=>b(e)?b(e,2)?e:U(e):V(e,l,r)).then(e=>{if(e){if(b(e,2))return A(y({replace:s},O(e.to),{state:typeof e.to==`object`?y({},i,e.to.state):i,force:a}),t||l)}else e=P(l,r,!0,s,i);return N(l,r,e),e})}function se(e,t){let n=ie(e,t);return n?Promise.reject(n):Promise.resolve()}function j(e){let t=J.values().next().value;return t&&typeof t.runWithContext==`function`?t.runWithContext(e):e()}function M(e,t){let n,[r,i,a]=we(e,t);n=Ce(r.reverse(),`beforeRouteLeave`,e,t);for(let i of r)i.leaveGuards.forEach(r=>{n.push($(r,e,t))});let o=se.bind(null,e,t);return n.push(o),X(n).then(()=>{n=[];for(let r of l.list())n.push($(r,e,t));return n.push(o),X(n)}).then(()=>{n=Ce(i,`beforeRouteUpdate`,e,t);for(let r of i)r.updateGuards.forEach(r=>{n.push($(r,e,t))});return n.push(o),X(n)}).then(()=>{n=[];for(let r of a)if(r.beforeEnter)if(_(r.beforeEnter))for(let i of r.beforeEnter)n.push($(i,e,t));else n.push($(r.beforeEnter,e,t));return n.push(o),X(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=Ce(a,`beforeRouteEnter`,e,t,j),n.push(o),X(n))).then(()=>{n=[];for(let r of u.list())n.push($(r,e,t));return n.push(o),X(n)}).catch(e=>b(e,8)?e:Promise.reject(e))}function N(e,t,n){d.list().forEach(r=>j(()=>r(e,t,n)))}function P(e,t,n,r,i){let a=ie(e,t);if(a)return a;let o=t===K,s=T?history.state:{};n&&(r||o?c.replace(e.fullPath,y({scroll:o&&s&&s.scroll},i)):c.push(e.fullPath,i)),f.value=e,W(e,t,n,o),U()}let F;function le(){F||=c.listen((e,t,n)=>{if(!Y.listening)return;let r=D(e),i=oe(r,Y.currentRoute.value);if(i){A(y(i,{replace:!0,force:!0}),r).catch(w);return}p=r;let a=f.value;T&&ge(me(a.fullPath,n.delta),Z()),M(r,a).catch(e=>b(e,12)?e:b(e,2)?(A(y(O(e.to),{force:!0}),r).then(e=>{b(e,20)&&!n.delta&&n.type===`pop`&&c.go(-1,!1)}).catch(w),Promise.reject()):(n.delta&&c.go(-n.delta,!1),V(e,r,a))).then(e=>{e||=P(r,a,!1),e&&(n.delta&&!b(e,8)?c.go(-n.delta,!1):n.type===`pop`&&b(e,20)&&c.go(-1,!1)),N(r,a,e)}).catch(w)})}let L=Q(),R=Q(),B;function V(e,t,n){U(e);let r=R.list();return r.length?r.forEach(r=>r(e,t,n)):console.error(e),Promise.reject(e)}function H(){return B&&f.value!==K?Promise.resolve():new Promise((e,t)=>{L.add([e,t])})}function U(e){return B||(B=!e,le(),L.list().forEach(([t,n])=>e?n(e):t()),L.reset()),e}function W(n,r,i,a){let{scrollBehavior:o}=e;if(!T||!o)return Promise.resolve();let s=!i&&_e(me(n.fullPath,0))||(a||!i)&&history.state&&history.state.scroll||null;return t().then(()=>o(n,r,s)).then(e=>n===f.value&&e&&pe(e)).catch(e=>n===f.value&&V(e,n,r))}let G=e=>c.go(e),q,J=new Set,Y={currentRoute:f,listening:!0,addRoute:E,removeRoute:te,clearRoutes:n.clearRoutes,hasRoute:re,getRoutes:ne,resolve:D,options:e,push:k,replace:ae,go:G,back:()=>G(-1),forward:()=>G(1),beforeEach:l.add,beforeResolve:u.add,afterEach:d.add,onError:R.add,isReady:H,install(e){e.component(`RouterLink`,et),e.component(`RouterView`,st),e.config.globalProperties.$router=Y,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>a(f)}),T&&!q&&f.value===K&&(q=!0,k(c.location).catch(e=>{}));let t={};for(let e in K)Object.defineProperty(t,e,{get:()=>f.value[e],enumerable:!0});e.provide(h,Y),e.provide(m,i(t)),e.provide(ee,f);let n=e.unmount;J.add(e),e.unmount=function(){J.delete(e),J.size<1&&(p=K,F&&F(),F=null,f.value=K,q=!1,B=!1),n()}}};function X(e){return e.reduce((e,t)=>e.then(()=>j(t)),Promise.resolve())}return Y}export{Ae as i,st as n,ct as r,et as t};
|
package/dist/web/index.html
CHANGED
|
@@ -9,14 +9,15 @@
|
|
|
9
9
|
/>
|
|
10
10
|
<link rel="icon" type="image/png" href="/assets/fuli-logo-ER1wQ8Kk.png" />
|
|
11
11
|
<title>复利 · Context Graph</title>
|
|
12
|
-
<script type="module" crossorigin src="/assets/index-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/i18n-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/console-
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/vue-router-
|
|
12
|
+
<script type="module" crossorigin src="/assets/index-F5e2sQ7p.js"></script>
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/i18n-CWfd8Dtt.js">
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/console-DMvHxKf9.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/useApi-CROJJdhE-BLQiPVw0.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/vue-router-DN8x6iY1.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/fuli-logo-Bu9WBuQe.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BDNMzG2s.js">
|
|
19
|
-
<link rel="
|
|
19
|
+
<link rel="modulepreload" crossorigin href="/assets/paths-CDREouhi.js">
|
|
20
|
+
<link rel="stylesheet" crossorigin href="/assets/index-X2j29j8i.css">
|
|
20
21
|
</head>
|
|
21
22
|
<body>
|
|
22
23
|
<div id="app"></div>
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from contextlib import asynccontextmanager
|
|
2
2
|
from typing import Annotated
|
|
3
3
|
|
|
4
|
-
from fastapi import Depends, FastAPI, Header, Query
|
|
4
|
+
from fastapi import Depends, FastAPI, Header, HTTPException, Query
|
|
5
5
|
|
|
6
|
-
from .auth import
|
|
6
|
+
from .auth import (
|
|
7
|
+
matches_bootstrap_token,
|
|
8
|
+
matches_human_review_token,
|
|
9
|
+
matches_workflow_observation_token,
|
|
10
|
+
)
|
|
7
11
|
from .config import Settings, get_settings
|
|
8
12
|
from .graph_models import GraphResult
|
|
9
13
|
from .knowledge_usage_models import KnowledgeUsageCreate, KnowledgeUsageResult
|
|
@@ -30,7 +34,30 @@ from .project_action_models import (
|
|
|
30
34
|
KnowledgeProjectActionResult,
|
|
31
35
|
KnowledgeProjectPreviewRecord,
|
|
32
36
|
KnowledgeProjectPreviewRequest,
|
|
37
|
+
PersonalProjectRelationReviewRecord,
|
|
38
|
+
PersonalProjectRelationReviewRequest,
|
|
39
|
+
)
|
|
40
|
+
from .personal_global_preference_models import (
|
|
41
|
+
PersonalGlobalPreferenceDecisionApply,
|
|
42
|
+
PersonalGlobalPreferenceDecisionInspection,
|
|
43
|
+
PersonalGlobalPreferenceDecisionIntent,
|
|
44
|
+
PersonalGlobalPreferenceDecisionPreview,
|
|
45
|
+
PersonalGlobalPreferenceDecisionRecord,
|
|
46
|
+
PersonalGlobalPreferenceDecisionStatusRequest,
|
|
47
|
+
PersonalGlobalPreferenceDecisionStatusResult,
|
|
48
|
+
PersonalGlobalPreferenceScopeOptions,
|
|
49
|
+
PersonalGlobalPreferenceScopeOptionsRequest,
|
|
50
|
+
)
|
|
51
|
+
from .workflow_candidate_models import (
|
|
52
|
+
WorkflowCandidate,
|
|
53
|
+
WorkflowCandidatePage,
|
|
54
|
+
WorkflowCandidateReview,
|
|
55
|
+
WorkflowCandidateReviewIntent,
|
|
56
|
+
WorkflowCandidateReviewPreview,
|
|
57
|
+
WorkflowCandidateSearch,
|
|
58
|
+
WorkflowRecommendationPage,
|
|
33
59
|
)
|
|
60
|
+
from .workflow_observation_models import WorkflowTransitionObservation
|
|
34
61
|
from .models import (
|
|
35
62
|
BootstrapRequest,
|
|
36
63
|
BootstrapResult,
|
|
@@ -105,6 +132,7 @@ from .knowledge_management import (
|
|
|
105
132
|
from .project_knowledge import (
|
|
106
133
|
apply_knowledge_project_action,
|
|
107
134
|
preview_knowledge_project_action,
|
|
135
|
+
review_personal_project_relation,
|
|
108
136
|
)
|
|
109
137
|
from .preference_conflicts import (
|
|
110
138
|
complete_preference_conflict,
|
|
@@ -112,6 +140,20 @@ from .preference_conflicts import (
|
|
|
112
140
|
list_preference_conflicts,
|
|
113
141
|
resolve_preference_conflict,
|
|
114
142
|
)
|
|
143
|
+
from .personal_global_preferences import (
|
|
144
|
+
apply_personal_global_preference_decision,
|
|
145
|
+
inspect_personal_global_preference_decision,
|
|
146
|
+
personal_global_preference_decision_status,
|
|
147
|
+
personal_global_preference_scope_options,
|
|
148
|
+
preview_personal_global_preference_decision,
|
|
149
|
+
)
|
|
150
|
+
from .workflow_candidates import (
|
|
151
|
+
preview_workflow_candidate_review,
|
|
152
|
+
recommend_workflow_candidates,
|
|
153
|
+
review_workflow_candidate,
|
|
154
|
+
search_workflow_candidates,
|
|
155
|
+
)
|
|
156
|
+
from .workflow_observations import record_workflow_transition_observation
|
|
115
157
|
from .runtime import GraphitiRuntime
|
|
116
158
|
from .store import GraphStore
|
|
117
159
|
|
|
@@ -147,6 +189,51 @@ def create_app(settings: Settings | None = None) -> FastAPI:
|
|
|
147
189
|
|
|
148
190
|
Actor = Annotated[dict, Depends(current_actor)]
|
|
149
191
|
|
|
192
|
+
async def current_human_reviewer(
|
|
193
|
+
actor: Actor,
|
|
194
|
+
x_fuli_human_review_token: Annotated[str | None, Header()] = None,
|
|
195
|
+
) -> dict:
|
|
196
|
+
if not resolved_settings.human_review_token:
|
|
197
|
+
raise HTTPException(
|
|
198
|
+
status_code=503,
|
|
199
|
+
detail='human workflow review channel is not configured',
|
|
200
|
+
)
|
|
201
|
+
if not matches_human_review_token(
|
|
202
|
+
x_fuli_human_review_token,
|
|
203
|
+
resolved_settings.human_review_token,
|
|
204
|
+
):
|
|
205
|
+
raise HTTPException(
|
|
206
|
+
status_code=403,
|
|
207
|
+
detail='independent human review proof required',
|
|
208
|
+
)
|
|
209
|
+
return {**actor, '_human_review_verified': True}
|
|
210
|
+
|
|
211
|
+
HumanReviewer = Annotated[dict, Depends(current_human_reviewer)]
|
|
212
|
+
|
|
213
|
+
async def current_workflow_observer(
|
|
214
|
+
actor: Actor,
|
|
215
|
+
x_fuli_workflow_observation_token: Annotated[
|
|
216
|
+
str | None,
|
|
217
|
+
Header(),
|
|
218
|
+
] = None,
|
|
219
|
+
) -> dict:
|
|
220
|
+
if not resolved_settings.workflow_observation_token:
|
|
221
|
+
raise HTTPException(
|
|
222
|
+
status_code=503,
|
|
223
|
+
detail='MCP host workflow observation channel is not configured',
|
|
224
|
+
)
|
|
225
|
+
if not matches_workflow_observation_token(
|
|
226
|
+
x_fuli_workflow_observation_token,
|
|
227
|
+
resolved_settings.workflow_observation_token,
|
|
228
|
+
):
|
|
229
|
+
raise HTTPException(
|
|
230
|
+
status_code=403,
|
|
231
|
+
detail='independent MCP host observation proof required',
|
|
232
|
+
)
|
|
233
|
+
return actor
|
|
234
|
+
|
|
235
|
+
WorkflowObserver = Annotated[dict, Depends(current_workflow_observer)]
|
|
236
|
+
|
|
150
237
|
@application.get('/health')
|
|
151
238
|
async def health() -> dict:
|
|
152
239
|
return await store.health()
|
|
@@ -337,6 +424,137 @@ def create_app(settings: Settings | None = None) -> FastAPI:
|
|
|
337
424
|
async def commit_personal(request: KnowledgeCommit, actor: Actor) -> CommitResult:
|
|
338
425
|
return await store.commit_personal(actor, request)
|
|
339
426
|
|
|
427
|
+
@application.post('/v1/workflow-observations', response_model=CommitResult)
|
|
428
|
+
async def record_workflow_observation(
|
|
429
|
+
request: WorkflowTransitionObservation,
|
|
430
|
+
actor: WorkflowObserver,
|
|
431
|
+
) -> CommitResult:
|
|
432
|
+
return await record_workflow_transition_observation(store, actor, request)
|
|
433
|
+
|
|
434
|
+
@application.post(
|
|
435
|
+
'/v1/personal-global-preference-candidates/decision-status',
|
|
436
|
+
response_model=PersonalGlobalPreferenceDecisionStatusResult,
|
|
437
|
+
)
|
|
438
|
+
async def personal_global_preference_status(
|
|
439
|
+
request: PersonalGlobalPreferenceDecisionStatusRequest,
|
|
440
|
+
actor: Actor,
|
|
441
|
+
) -> PersonalGlobalPreferenceDecisionStatusResult:
|
|
442
|
+
return await personal_global_preference_decision_status(
|
|
443
|
+
store,
|
|
444
|
+
actor,
|
|
445
|
+
request,
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
@application.post(
|
|
449
|
+
'/v1/personal-global-preference-candidates/{candidate_id}/scope-options',
|
|
450
|
+
response_model=PersonalGlobalPreferenceScopeOptions,
|
|
451
|
+
)
|
|
452
|
+
async def personal_global_preference_scopes(
|
|
453
|
+
candidate_id: str,
|
|
454
|
+
request: PersonalGlobalPreferenceScopeOptionsRequest,
|
|
455
|
+
actor: Actor,
|
|
456
|
+
) -> PersonalGlobalPreferenceScopeOptions:
|
|
457
|
+
return await personal_global_preference_scope_options(
|
|
458
|
+
store,
|
|
459
|
+
actor,
|
|
460
|
+
candidate_id,
|
|
461
|
+
request,
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
@application.post(
|
|
465
|
+
'/v1/personal-global-preference-candidates/{candidate_id}/decision-inspection',
|
|
466
|
+
response_model=PersonalGlobalPreferenceDecisionInspection,
|
|
467
|
+
)
|
|
468
|
+
async def inspect_personal_global_preference(
|
|
469
|
+
candidate_id: str,
|
|
470
|
+
request: PersonalGlobalPreferenceDecisionIntent,
|
|
471
|
+
actor: Actor,
|
|
472
|
+
) -> PersonalGlobalPreferenceDecisionInspection:
|
|
473
|
+
return await inspect_personal_global_preference_decision(
|
|
474
|
+
store,
|
|
475
|
+
actor,
|
|
476
|
+
candidate_id,
|
|
477
|
+
request,
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
@application.post(
|
|
481
|
+
'/v1/personal-global-preference-candidates/{candidate_id}/decision-preview',
|
|
482
|
+
response_model=PersonalGlobalPreferenceDecisionPreview,
|
|
483
|
+
)
|
|
484
|
+
async def preview_personal_global_preference(
|
|
485
|
+
candidate_id: str,
|
|
486
|
+
request: PersonalGlobalPreferenceDecisionIntent,
|
|
487
|
+
actor: HumanReviewer,
|
|
488
|
+
) -> PersonalGlobalPreferenceDecisionPreview:
|
|
489
|
+
return await preview_personal_global_preference_decision(
|
|
490
|
+
store,
|
|
491
|
+
actor,
|
|
492
|
+
candidate_id,
|
|
493
|
+
request,
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
@application.post(
|
|
497
|
+
'/v1/personal-global-preference-candidates/{candidate_id}/decision',
|
|
498
|
+
response_model=PersonalGlobalPreferenceDecisionRecord,
|
|
499
|
+
)
|
|
500
|
+
async def apply_personal_global_preference(
|
|
501
|
+
candidate_id: str,
|
|
502
|
+
request: PersonalGlobalPreferenceDecisionApply,
|
|
503
|
+
actor: HumanReviewer,
|
|
504
|
+
) -> PersonalGlobalPreferenceDecisionRecord:
|
|
505
|
+
return await apply_personal_global_preference_decision(
|
|
506
|
+
store,
|
|
507
|
+
actor,
|
|
508
|
+
candidate_id,
|
|
509
|
+
request,
|
|
510
|
+
)
|
|
511
|
+
|
|
512
|
+
@application.post(
|
|
513
|
+
'/v1/workflow-candidates/recommendations',
|
|
514
|
+
response_model=WorkflowRecommendationPage,
|
|
515
|
+
)
|
|
516
|
+
async def workflow_candidate_recommendations(
|
|
517
|
+
request: WorkflowCandidateSearch,
|
|
518
|
+
actor: Actor,
|
|
519
|
+
) -> WorkflowRecommendationPage:
|
|
520
|
+
return await recommend_workflow_candidates(store, actor, request)
|
|
521
|
+
|
|
522
|
+
@application.post(
|
|
523
|
+
'/v1/workflow-candidates/search',
|
|
524
|
+
response_model=WorkflowCandidatePage,
|
|
525
|
+
)
|
|
526
|
+
async def workflow_candidate_search(
|
|
527
|
+
request: WorkflowCandidateSearch,
|
|
528
|
+
actor: Actor,
|
|
529
|
+
) -> WorkflowCandidatePage:
|
|
530
|
+
return await search_workflow_candidates(store, actor, request)
|
|
531
|
+
|
|
532
|
+
@application.post(
|
|
533
|
+
'/v1/workflow-candidates/{candidate_id}/review-preview',
|
|
534
|
+
response_model=WorkflowCandidateReviewPreview,
|
|
535
|
+
)
|
|
536
|
+
async def preview_workflow_review(
|
|
537
|
+
candidate_id: str,
|
|
538
|
+
request: WorkflowCandidateReviewIntent,
|
|
539
|
+
actor: HumanReviewer,
|
|
540
|
+
) -> WorkflowCandidateReviewPreview:
|
|
541
|
+
return await preview_workflow_candidate_review(
|
|
542
|
+
store, actor, candidate_id, request
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
@application.post(
|
|
546
|
+
'/v1/workflow-candidates/{candidate_id}/review',
|
|
547
|
+
response_model=WorkflowCandidate,
|
|
548
|
+
)
|
|
549
|
+
async def review_workflow(
|
|
550
|
+
candidate_id: str,
|
|
551
|
+
request: WorkflowCandidateReview,
|
|
552
|
+
actor: HumanReviewer,
|
|
553
|
+
) -> WorkflowCandidate:
|
|
554
|
+
return await review_workflow_candidate(
|
|
555
|
+
store, actor, candidate_id, request
|
|
556
|
+
)
|
|
557
|
+
|
|
340
558
|
@application.post(
|
|
341
559
|
'/v1/knowledge/reviews/start',
|
|
342
560
|
response_model=KnowledgeReviewRun,
|
|
@@ -577,6 +795,24 @@ def create_app(settings: Settings | None = None) -> FastAPI:
|
|
|
577
795
|
) -> KnowledgeProjectActionResult:
|
|
578
796
|
return await apply_knowledge_project_action(store, actor, item_id, request)
|
|
579
797
|
|
|
798
|
+
@application.post(
|
|
799
|
+
'/v1/personal-spaces/{space_id}/project-relations/{relation_id}/review',
|
|
800
|
+
response_model=PersonalProjectRelationReviewRecord,
|
|
801
|
+
)
|
|
802
|
+
async def review_local_project_relation(
|
|
803
|
+
space_id: str,
|
|
804
|
+
relation_id: str,
|
|
805
|
+
request: PersonalProjectRelationReviewRequest,
|
|
806
|
+
actor: HumanReviewer,
|
|
807
|
+
) -> PersonalProjectRelationReviewRecord:
|
|
808
|
+
return await review_personal_project_relation(
|
|
809
|
+
store,
|
|
810
|
+
actor,
|
|
811
|
+
space_id,
|
|
812
|
+
relation_id,
|
|
813
|
+
request,
|
|
814
|
+
)
|
|
815
|
+
|
|
580
816
|
@application.post(
|
|
581
817
|
'/v1/projects/{project_id}/proposals',
|
|
582
818
|
response_model=ProposalRecord,
|
|
@@ -15,3 +15,21 @@ def matches_bootstrap_token(provided: str | None, expected: str) -> bool:
|
|
|
15
15
|
if not provided:
|
|
16
16
|
return False
|
|
17
17
|
return hmac.compare_digest(provided, expected)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def matches_human_review_token(
|
|
21
|
+
provided: str | None,
|
|
22
|
+
expected: str | None,
|
|
23
|
+
) -> bool:
|
|
24
|
+
if not provided or not expected:
|
|
25
|
+
return False
|
|
26
|
+
return hmac.compare_digest(provided, expected)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def matches_workflow_observation_token(
|
|
30
|
+
provided: str | None,
|
|
31
|
+
expected: str | None,
|
|
32
|
+
) -> bool:
|
|
33
|
+
if not provided or not expected:
|
|
34
|
+
return False
|
|
35
|
+
return hmac.compare_digest(provided, expected)
|