insightfactory-cli 1.0.3.dev19__tar.gz → 1.0.3.dev21__tar.gz
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.
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/PKG-INFO +7 -1
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/README.md +6 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/pyproject.toml +1 -1
- insightfactory_cli-1.0.3.dev21/src/if_cli/assets/__init__.py +1 -0
- insightfactory_cli-1.0.3.dev21/src/if_cli/assets/insightfactoryai-logo.svg +55 -0
- insightfactory_cli-1.0.3.dev21/src/if_cli/callback_page.py +215 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/mcp.py +2 -1
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/oauth.py +5 -4
- insightfactory_cli-1.0.3.dev21/src/if_cli/router/log.py +13 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/router/server.py +1 -5
- insightfactory_cli-1.0.3.dev21/src/if_cli/router/upstream.py +272 -0
- insightfactory_cli-1.0.3.dev21/tests/test_router_upstream.py +370 -0
- insightfactory_cli-1.0.3.dev19/src/if_cli/router/upstream.py +0 -107
- insightfactory_cli-1.0.3.dev19/tests/test_router_upstream.py +0 -80
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/.github/workflows/ci.yml +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/.github/workflows/claude.yml +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/.github/workflows/release.yml +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/.gitignore +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/.python-version +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/AGENTS.md +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/CLAUDE.md +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/LICENSE +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/__init__.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/__main__.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/cache.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/cli.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/colour.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/__init__.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/api.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/config.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/login.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/logout.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/profiles.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/set_token.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/token.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/config.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/constants.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/http.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/main.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/router/__init__.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/router/catalog.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/router/policy.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/runtime.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/__init__.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/cache_writer.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/conftest.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/helpers.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/servers.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_api.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_api_command.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_cache.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_cli.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_config.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_config_command.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_login.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_mcp_command.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_oauth.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_oauth_flow.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_oauth_force_refresh.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_profiles.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_programmatic_api.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_router_catalog.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_router_policy.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_router_server.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_runtime.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_set_token.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/tests/test_token.py +0 -0
- {insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: insightfactory-cli
|
|
3
|
-
Version: 1.0.3.
|
|
3
|
+
Version: 1.0.3.dev21
|
|
4
4
|
Summary: Profile-based authentication CLI for the InsightFactory Interfaces API
|
|
5
5
|
Project-URL: Homepage, https://insightfactory.ai
|
|
6
6
|
Author-email: "insightfactory.ai Support" <support@insightfactory.ai>
|
|
@@ -304,6 +304,12 @@ Passing dev-only writes to production means changing an argument value, not
|
|
|
304
304
|
connecting to a different server, so keep `--writable` scoped to the
|
|
305
305
|
environments meant to be written by hand.
|
|
306
306
|
|
|
307
|
+
A tool the factory will not run until someone finishes a step in a browser, such
|
|
308
|
+
as linking a personal Databricks identity, comes back as a failed call naming the
|
|
309
|
+
page to visit rather than as a prompt. The router never relays the factory's
|
|
310
|
+
request for input to the model, and it names a page only on that environment's
|
|
311
|
+
own origin, logging a `WARN` line on stderr when it drops one that is not.
|
|
312
|
+
|
|
307
313
|
## Development
|
|
308
314
|
|
|
309
315
|
```bash
|
|
@@ -280,6 +280,12 @@ Passing dev-only writes to production means changing an argument value, not
|
|
|
280
280
|
connecting to a different server, so keep `--writable` scoped to the
|
|
281
281
|
environments meant to be written by hand.
|
|
282
282
|
|
|
283
|
+
A tool the factory will not run until someone finishes a step in a browser, such
|
|
284
|
+
as linking a personal Databricks identity, comes back as a failed call naming the
|
|
285
|
+
page to visit rather than as a prompt. The router never relays the factory's
|
|
286
|
+
request for input to the model, and it names a page only on that environment's
|
|
287
|
+
own origin, logging a `WARN` line on stderr when it drops one that is not.
|
|
288
|
+
|
|
283
289
|
## Development
|
|
284
290
|
|
|
285
291
|
```bash
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Static files shipped with the CLI."""
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<svg class="logo" role="img" aria-label="insightfactory.ai" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 286.67 62.53">
|
|
2
|
+
<defs>
|
|
3
|
+
<style>
|
|
4
|
+
.iflogo-1 {
|
|
5
|
+
fill: #fab314;
|
|
6
|
+
}
|
|
7
|
+
.iflogo-2 {
|
|
8
|
+
fill: #f8e86c;
|
|
9
|
+
}
|
|
10
|
+
.iflogo-3 {
|
|
11
|
+
fill: #fad121;
|
|
12
|
+
}
|
|
13
|
+
.iflogo-4 {
|
|
14
|
+
fill: #1f252e;
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</defs>
|
|
18
|
+
<g id="ARTWORK">
|
|
19
|
+
<g>
|
|
20
|
+
<g>
|
|
21
|
+
<polygon class="iflogo-4" points="32.49 37.52 32.5 37.53 32.49 37.52 32.49 37.52"/>
|
|
22
|
+
<polygon class="iflogo-4" points="21.66 18.76 0 31.27 21.66 43.78 21.66 18.76"/>
|
|
23
|
+
<g>
|
|
24
|
+
<polygon class="iflogo-4" points="43.32 31.27 43.32 43.78 54.15 37.52 43.32 31.27"/>
|
|
25
|
+
<polygon class="iflogo-4" points="43.32 43.78 43.32 56.28 54.15 62.53 64.98 56.28 43.32 43.78"/>
|
|
26
|
+
</g>
|
|
27
|
+
<polygon class="iflogo-2" points="21.66 6.26 32.49 12.51 43.32 6.26 32.48 0 21.66 6.26"/>
|
|
28
|
+
<polygon class="iflogo-3" points="32.49 12.51 32.49 12.51 21.66 6.26 21.66 18.76 21.66 18.76 21.66 43.78 32.49 50.03 32.49 37.52 32.49 12.51"/>
|
|
29
|
+
<g>
|
|
30
|
+
<polygon class="iflogo-1" points="32.49 12.51 32.5 25.02 43.32 18.76 43.32 6.26 32.49 12.51"/>
|
|
31
|
+
<polygon class="iflogo-1" points="43.32 56.28 43.32 43.78 43.32 31.27 32.49 37.52 32.49 50.03 43.32 56.28"/>
|
|
32
|
+
</g>
|
|
33
|
+
</g>
|
|
34
|
+
<g>
|
|
35
|
+
<path class="iflogo-4" d="m75.28,23.74c-.81,0-1.47-.27-1.99-.8-.52-.53-.77-1.17-.77-1.91s.26-1.41.77-1.93,1.18-.78,1.99-.78c.76,0,1.41.26,1.94.78.53.52.79,1.17.79,1.93s-.26,1.38-.79,1.91c-.53.53-1.17.8-1.94.8Zm-2.19,2.23h4.31v17.39h-4.31v-17.39Z"/>
|
|
36
|
+
<path class="iflogo-4" d="m79.46,25.97h3.91l.3,1.77c.54-.63,1.2-1.12,1.97-1.48.78-.36,1.61-.54,2.51-.54,1.33,0,2.46.29,3.39.87.93.58,1.65,1.42,2.16,2.52.51,1.1.76,2.46.76,4.09v10.16h-4.35v-9.57c0-1.34-.26-2.35-.78-3.03s-1.29-1.01-2.33-1.01-1.86.34-2.41,1.03c-.55.68-.83,1.7-.83,3.04v9.53h-4.31v-17.39Z"/>
|
|
37
|
+
<path class="iflogo-4" d="m100.08,37.69c.13.58.36,1.02.69,1.32.33.3.7.52,1.11.64.42.13.84.19,1.26.19.79,0,1.4-.16,1.85-.47.45-.31.67-.71.67-1.2,0-.42-.16-.75-.47-.99-.31-.24-.71-.43-1.2-.57-.48-.14-.99-.27-1.53-.38-.61-.16-1.25-.34-1.94-.54-.69-.2-1.33-.48-1.94-.85-.61-.37-1.11-.85-1.5-1.44-.39-.59-.59-1.34-.59-2.24,0-1.09.28-2.03.84-2.83.56-.8,1.35-1.43,2.38-1.9s2.21-.7,3.56-.7c1.59,0,2.94.35,4.04,1.04,1.1.7,1.9,1.69,2.39,2.99l-3.78,1.11c-.13-.32-.34-.59-.61-.8s-.59-.36-.96-.45c-.37-.09-.75-.14-1.13-.14-.65,0-1.19.13-1.62.4-.43.27-.64.63-.64,1.1,0,.28.08.5.24.68s.38.32.66.43c.28.12.61.22.98.31.37.09.78.2,1.23.31.7.19,1.4.4,2.11.64.71.24,1.36.55,1.96.92.59.37,1.07.87,1.43,1.5.36.63.56,1.42.61,2.37,0,1.02-.28,1.94-.84,2.77s-1.37,1.48-2.43,1.96c-1.06.49-2.34.73-3.84.73-1.75,0-3.24-.38-4.47-1.15s-2.03-1.96-2.41-3.58l3.88-1.18Z"/>
|
|
38
|
+
<path class="iflogo-4" d="m114.61,23.74c-.81,0-1.47-.27-1.99-.8-.52-.53-.77-1.17-.77-1.91s.26-1.41.77-1.93,1.18-.78,1.99-.78c.76,0,1.41.26,1.94.78.53.52.79,1.17.79,1.93s-.26,1.38-.79,1.91c-.53.53-1.17.8-1.94.8Zm-2.19,2.23h4.31v17.39h-4.31v-17.39Z"/>
|
|
39
|
+
<path class="iflogo-4" d="m131.9,25.97h3.91v14.82c0,1.97-.47,3.67-1.42,5.1-.94,1.43-2.31,2.52-4.09,3.29-1.79.76-3.93,1.15-6.42,1.15l-.67-3.76c2.72-.05,4.78-.54,6.18-1.5s2.11-2.32,2.11-4.1v-.07l.57-.21c-.54.81-1.28,1.5-2.22,2.07s-2.07.85-3.37.85c-1.48,0-2.79-.37-3.91-1.11-1.12-.74-2.01-1.78-2.65-3.11-.64-1.33-.96-2.91-.96-4.71s.32-3.39.96-4.73c.64-1.34,1.52-2.38,2.65-3.11,1.12-.73,2.43-1.1,3.91-1.1.76,0,1.48.11,2.14.33.66.22,1.25.51,1.75.87.5.36.93.76,1.26,1.2l.27-2.16Zm-8.32,8.7c0,1.46.37,2.64,1.09,3.53.73.89,1.7,1.34,2.92,1.34.7,0,1.34-.19,1.92-.57.58-.38,1.06-.94,1.43-1.69.37-.74.56-1.61.56-2.61s-.19-1.92-.56-2.64c-.37-.72-.85-1.27-1.45-1.65-.59-.38-1.23-.57-1.9-.57-1.21,0-2.19.45-2.92,1.34-.73.89-1.09,2.07-1.09,3.53Z"/>
|
|
40
|
+
<path class="iflogo-4" d="m138.5,18.32h4.31v9.36c.52-.58,1.16-1.05,1.94-1.41.78-.36,1.65-.54,2.61-.54,1.28,0,2.39.29,3.34.87.94.58,1.68,1.42,2.21,2.52.53,1.1.79,2.46.79,4.09v10.16h-4.55v-9.57c0-1.34-.26-2.35-.78-3.03s-1.29-1.01-2.33-1.01-1.86.37-2.41,1.1c-.55.73-.83,1.77-.83,3.11v9.39h-4.31v-25.04Z"/>
|
|
41
|
+
<path class="iflogo-4" d="m157.01,25.97v-4.87h4.35v4.87h3.74v3.93h-3.74v7.06c0,.9.19,1.54.57,1.91.38.37.86.57,1.43.59.57.02,1.15-.01,1.74-.1v3.83c-1.03.23-2.04.3-3.02.21-.98-.09-1.85-.37-2.61-.82-.76-.45-1.36-1.14-1.8-2.07-.44-.93-.66-2.11-.66-3.55v-7.06h-2.39v-3.93h2.39Z"/>
|
|
42
|
+
<path class="iflogo-4" d="m170.42,23.92c0-1.27.2-2.35.61-3.23s1.05-1.52,1.94-1.93c.89-.41,2.07-.55,3.56-.43v2.33c-1.35-.12-2.28.11-2.8.68s-.78,1.43-.78,2.59v2.05h3.71v2.43h-3.71v14.96h-2.53v-14.96h-2.36v-2.43h2.36v-2.05Z"/>
|
|
43
|
+
<path class="iflogo-4" d="m188.25,43.36l-.2-3.13c-.47,1.07-1.17,1.9-2.09,2.49-.92.59-2.09.89-3.5.89-1.21,0-2.25-.2-3.1-.59-.85-.39-1.51-.96-1.97-1.69-.46-.73-.69-1.59-.69-2.59,0-1.46.53-2.66,1.58-3.6,1.06-.94,2.58-1.51,4.58-1.72l5.19-.59v-1.39c0-.97-.35-1.76-1.04-2.35s-1.64-.89-2.83-.89-2.14.28-2.92.83c-.78.56-1.31,1.36-1.6,2.4l-2.29-.83c.45-1.53,1.28-2.72,2.48-3.58,1.2-.86,2.67-1.29,4.4-1.29,2,0,3.56.53,4.67,1.58,1.11,1.06,1.67,2.49,1.67,4.3v11.76h-2.33Zm-.2-8.31l-5.22.63c-1.12.14-1.98.46-2.56.96-.58.5-.88,1.15-.88,1.96s.29,1.46.86,1.95c.57.49,1.4.73,2.48.73,1.24,0,2.25-.25,3.03-.77.79-.51,1.37-1.2,1.74-2.07.37-.87.56-1.81.56-2.83v-.56Z"/>
|
|
44
|
+
<path class="iflogo-4" d="m201.02,43.61c-1.64,0-3.08-.37-4.31-1.11-1.24-.74-2.2-1.78-2.88-3.11-.69-1.33-1.03-2.88-1.03-4.64s.34-3.36,1.03-4.71,1.65-2.41,2.88-3.17c1.24-.75,2.67-1.13,4.31-1.13,1.73,0,3.25.41,4.55,1.23,1.3.82,2.25,1.97,2.83,3.43l-2.33.83c-.34-.93-.95-1.66-1.84-2.21-.89-.54-1.92-.82-3.08-.82s-2.14.27-2.98.8-1.49,1.29-1.96,2.26c-.46.97-.69,2.12-.69,3.44,0,1.95.51,3.51,1.52,4.68s2.36,1.76,4.04,1.76c1.15,0,2.17-.27,3.07-.8.9-.53,1.56-1.25,1.99-2.16l2.29.83c-.61,1.44-1.56,2.56-2.86,3.38-1.3.81-2.82,1.22-4.55,1.22Z"/>
|
|
45
|
+
<path class="iflogo-4" d="m212.07,25.97v-4.87h2.53v4.87h4.48v2.43h-4.48v9.36c0,1.07.22,1.84.66,2.33.44.49,1,.78,1.68.87.69.09,1.4.09,2.14,0v2.26c-.88.21-1.74.27-2.58.17-.84-.09-1.6-.35-2.26-.78-.66-.43-1.19-1.04-1.58-1.83-.39-.79-.59-1.8-.59-3.03v-9.36h-2.53v-2.43h2.53Z"/>
|
|
46
|
+
<path class="iflogo-4" d="m228.49,43.61c-1.6,0-3.02-.36-4.28-1.08-1.26-.72-2.25-1.74-2.97-3.08-.72-1.33-1.08-2.92-1.08-4.75s.37-3.46,1.1-4.8c.73-1.34,1.73-2.38,3-3.1,1.27-.72,2.7-1.08,4.3-1.08s3.03.36,4.3,1.08c1.27.72,2.27,1.75,3,3.08.73,1.33,1.1,2.92,1.1,4.75s-.37,3.46-1.11,4.8-1.75,2.38-3.03,3.1-2.72,1.08-4.31,1.08Zm-.03-2.47c.99,0,1.92-.23,2.8-.68.88-.45,1.59-1.16,2.14-2.12.55-.96.83-2.19.83-3.67s-.27-2.74-.81-3.69c-.54-.95-1.24-1.65-2.11-2.1s-1.79-.68-2.78-.68-1.91.23-2.76.68-1.54,1.16-2.07,2.12c-.53.96-.79,2.19-.79,3.67s.26,2.74.78,3.69c.52.95,1.2,1.65,2.04,2.1.84.45,1.76.68,2.75.68Z"/>
|
|
47
|
+
<path class="iflogo-4" d="m238.93,25.97h2.33l.13,2.54c.45-.63.99-1.16,1.63-1.6.64-.44,1.35-.75,2.12-.92.77-.17,1.6-.18,2.48-.02v2.61c-.94-.18-1.79-.18-2.54,0-.75.19-1.4.53-1.94,1.04-.54.51-.96,1.15-1.25,1.93-.29.78-.44,1.68-.44,2.7v9.11h-2.53v-17.39Z"/>
|
|
48
|
+
<path class="iflogo-4" d="m262.19,25.97h2.63l-9.64,24.35h-2.43l2.87-7.2-6.81-17.15h2.76l5.39,14.05,5.22-14.05Z"/>
|
|
49
|
+
<path class="iflogo-4" d="m263.09,43.52c-.46,0-.84-.16-1.15-.5-.31-.33-.46-.73-.46-1.21s.15-.88.46-1.21c.31-.33.69-.5,1.15-.5s.82.17,1.14.5c.32.33.48.73.48,1.21s-.16.88-.48,1.21c-.32.33-.7.5-1.14.5Z"/>
|
|
50
|
+
<path class="iflogo-4" d="m278.25,43.36l-.2-3.13c-.47,1.07-1.17,1.9-2.09,2.49-.92.59-2.09.89-3.5.89-1.21,0-2.25-.2-3.1-.59-.85-.39-1.51-.96-1.97-1.69-.46-.73-.69-1.59-.69-2.59,0-1.46.53-2.66,1.58-3.6,1.06-.94,2.58-1.51,4.58-1.72l5.19-.59v-1.39c0-.97-.35-1.76-1.04-2.35s-1.64-.89-2.83-.89-2.14.28-2.92.83c-.78.56-1.31,1.36-1.6,2.4l-2.29-.83c.45-1.53,1.28-2.72,2.48-3.58,1.2-.86,2.67-1.29,4.4-1.29,2,0,3.56.53,4.67,1.58,1.11,1.06,1.67,2.49,1.67,4.3v11.76h-2.33Zm-.2-8.31l-5.22.63c-1.12.14-1.98.46-2.56.96-.58.5-.88,1.15-.88,1.96s.29,1.46.86,1.95c.57.49,1.4.73,2.48.73,1.24,0,2.25-.25,3.03-.77.79-.51,1.37-1.2,1.74-2.07.37-.87.56-1.81.56-2.83v-.56Z"/>
|
|
51
|
+
<path class="iflogo-4" d="m284.92,22.49c-.52,0-.94-.17-1.28-.52-.34-.35-.51-.78-.51-1.29s.17-.97.51-1.32.76-.52,1.28-.52c.47,0,.88.17,1.23.52.35.35.52.79.52,1.32s-.17.94-.52,1.29c-.35.35-.76.52-1.23.52Zm-1.28,3.48h2.49v17.39h-2.49v-17.39Z"/>
|
|
52
|
+
</g>
|
|
53
|
+
</g>
|
|
54
|
+
</g>
|
|
55
|
+
</svg>
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""Branded HTML for the loopback OAuth callback tab.
|
|
2
|
+
|
|
3
|
+
This tab is the frame straight after the Auth0 Universal Login widget, so it
|
|
4
|
+
copies that theme rather than the Interfaces app. Every value here mirrors
|
|
5
|
+
``auth0_branding_theme.insight_factory`` in
|
|
6
|
+
``terraform-Insightfactory-infrastructure/Auth0/modules/auth0/branding.tf``, and
|
|
7
|
+
the comments name the Terraform attribute each one came from. Change them together.
|
|
8
|
+
|
|
9
|
+
The page is self-contained: the logo is inline SVG and the CSS is inline, so it
|
|
10
|
+
renders from the loopback server with no network access beyond the webfont.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from functools import lru_cache
|
|
16
|
+
from importlib.resources import files
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@lru_cache(maxsize=1)
|
|
20
|
+
def logo_svg() -> str:
|
|
21
|
+
"""The wordmark Auth0 serves from the CDN, shipped with the package.
|
|
22
|
+
|
|
23
|
+
Auth0 loads it from cdn.insightfactory.ai. We inline the same file so the
|
|
24
|
+
callback page does not depend on the CDN being reachable.
|
|
25
|
+
"""
|
|
26
|
+
return files("if_cli.assets").joinpath("insightfactoryai-logo.svg").read_text(encoding="utf-8")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
STYLES = """\
|
|
30
|
+
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap");
|
|
31
|
+
|
|
32
|
+
:root {
|
|
33
|
+
--page-background: #20252e; /* page_background.background_color */
|
|
34
|
+
--widget-background: #ffffff; /* colors.widget_background */
|
|
35
|
+
--header: #20252e; /* colors.header */
|
|
36
|
+
--body-text: #20252e; /* colors.body_text */
|
|
37
|
+
--icons: #65676e; /* colors.icons */
|
|
38
|
+
--input-border: #c9cace; /* colors.input_border */
|
|
39
|
+
--success: #13a688; /* colors.success */
|
|
40
|
+
--error: #d03c38; /* colors.error */
|
|
41
|
+
--success-soft: rgba(19, 166, 136, 0.12);
|
|
42
|
+
--error-soft: rgba(208, 60, 56, 0.12);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
* {
|
|
46
|
+
box-sizing: border-box;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
body {
|
|
50
|
+
margin: 0;
|
|
51
|
+
min-height: 100vh;
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center; /* page_layout: center */
|
|
54
|
+
justify-content: center;
|
|
55
|
+
padding: 24px;
|
|
56
|
+
background: var(--page-background);
|
|
57
|
+
color: var(--body-text);
|
|
58
|
+
font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
59
|
+
font-size: 16px; /* fonts.reference_text_size */
|
|
60
|
+
font-weight: 300;
|
|
61
|
+
line-height: 1.5;
|
|
62
|
+
-webkit-font-smoothing: antialiased;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
main {
|
|
66
|
+
width: 100%;
|
|
67
|
+
max-width: 400px;
|
|
68
|
+
padding: 40px 32px 32px;
|
|
69
|
+
border-radius: 8px; /* borders.widget_corner_radius */
|
|
70
|
+
background: var(--widget-background);
|
|
71
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.28); /* borders.show_widget_shadow */
|
|
72
|
+
text-align: center; /* widget.header_text_alignment */
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.logo {
|
|
76
|
+
height: 68px; /* widget.logo_height */
|
|
77
|
+
width: auto;
|
|
78
|
+
max-width: 100%;
|
|
79
|
+
display: block;
|
|
80
|
+
margin: 0 auto 24px; /* widget.logo_position: center */
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.pill {
|
|
84
|
+
display: inline-flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
gap: 7px;
|
|
87
|
+
margin-bottom: 16px;
|
|
88
|
+
padding: 4px 12px 4px 10px;
|
|
89
|
+
border-radius: 999px;
|
|
90
|
+
background: var(--pill-soft);
|
|
91
|
+
color: var(--pill);
|
|
92
|
+
font-size: 14px;
|
|
93
|
+
font-weight: 500;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.dot {
|
|
97
|
+
width: 7px;
|
|
98
|
+
height: 7px;
|
|
99
|
+
border-radius: 50%;
|
|
100
|
+
background: currentColor;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
h1 {
|
|
104
|
+
margin: 0 0 10px;
|
|
105
|
+
color: var(--header); /* colors.header */
|
|
106
|
+
font-size: 24px; /* fonts.title: 150% of 16px */
|
|
107
|
+
font-weight: 300; /* fonts.title.bold = false */
|
|
108
|
+
line-height: 1.25;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
p {
|
|
112
|
+
margin: 0;
|
|
113
|
+
color: var(--icons);
|
|
114
|
+
font-size: 14px; /* fonts.subtitle: 87.5% of 16px */
|
|
115
|
+
font-weight: 400;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
code {
|
|
119
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
120
|
+
font-size: 13px;
|
|
121
|
+
color: var(--body-text);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
pre {
|
|
125
|
+
margin: 20px 0 0;
|
|
126
|
+
padding: 12px 14px;
|
|
127
|
+
border: 1px solid var(--input-border); /* colors.input_border */
|
|
128
|
+
border-radius: 3px; /* borders.input_border_radius */
|
|
129
|
+
color: var(--body-text);
|
|
130
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
131
|
+
font-size: 13px;
|
|
132
|
+
text-align: left;
|
|
133
|
+
white-space: pre-wrap;
|
|
134
|
+
word-break: break-word;
|
|
135
|
+
}
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
_TEMPLATE = """\
|
|
139
|
+
<!DOCTYPE html>
|
|
140
|
+
<html lang="en">
|
|
141
|
+
<head>
|
|
142
|
+
<meta charset="utf-8">
|
|
143
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
144
|
+
<title>{title} | insightfactory.ai</title>
|
|
145
|
+
<style>
|
|
146
|
+
{styles}
|
|
147
|
+
</style>
|
|
148
|
+
</head>
|
|
149
|
+
<body>
|
|
150
|
+
<main style="--pill: var({pill_colour}); --pill-soft: var({pill_soft});">
|
|
151
|
+
{logo}
|
|
152
|
+
<span class="pill"><span class="dot"></span>{pill}</span>
|
|
153
|
+
<h1>{heading}</h1>
|
|
154
|
+
<p>{message}</p>
|
|
155
|
+
{detail}
|
|
156
|
+
</main>
|
|
157
|
+
</body>
|
|
158
|
+
</html>
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def render(
|
|
163
|
+
*,
|
|
164
|
+
title: str,
|
|
165
|
+
pill: str,
|
|
166
|
+
heading: str,
|
|
167
|
+
message: str,
|
|
168
|
+
detail: str = "",
|
|
169
|
+
ok: bool = True,
|
|
170
|
+
) -> bytes:
|
|
171
|
+
"""Render one callback page, ready to write to the socket."""
|
|
172
|
+
return _TEMPLATE.format(
|
|
173
|
+
title=title,
|
|
174
|
+
styles=STYLES,
|
|
175
|
+
logo=logo_svg(),
|
|
176
|
+
pill=pill,
|
|
177
|
+
pill_colour="--success" if ok else "--error",
|
|
178
|
+
pill_soft="--success-soft" if ok else "--error-soft",
|
|
179
|
+
heading=heading,
|
|
180
|
+
message=message,
|
|
181
|
+
detail=detail,
|
|
182
|
+
).encode("utf-8")
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def success_page() -> bytes:
|
|
186
|
+
return render(
|
|
187
|
+
title="Login complete",
|
|
188
|
+
pill="Connected",
|
|
189
|
+
heading="Authentication successful",
|
|
190
|
+
message="You can close this tab and return to the terminal.",
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def failure_page(error: str, description: str) -> bytes:
|
|
195
|
+
return render(
|
|
196
|
+
title="Login failed",
|
|
197
|
+
pill="Not connected",
|
|
198
|
+
heading="Authentication failed",
|
|
199
|
+
message="Close this tab and run <code>if-cli login</code> again.",
|
|
200
|
+
detail=f"<pre>{error}: {description}</pre>" if error or description else "",
|
|
201
|
+
ok=False,
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def state_mismatch_page() -> bytes:
|
|
206
|
+
return render(
|
|
207
|
+
title="Login callback ignored",
|
|
208
|
+
pill="Not connected",
|
|
209
|
+
heading="Callback ignored",
|
|
210
|
+
message=(
|
|
211
|
+
"The callback state did not match the one this login started with, "
|
|
212
|
+
"so it was discarded. Close this tab and run <code>if-cli login</code> again."
|
|
213
|
+
),
|
|
214
|
+
ok=False,
|
|
215
|
+
)
|
{insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/commands/mcp.py
RENAMED
|
@@ -132,7 +132,8 @@ def mcp_command(argv: list[str]) -> None:
|
|
|
132
132
|
# import bug inside if_cli.router propagates instead of reading as a missing extra.
|
|
133
133
|
if importlib.util.find_spec("mcp") is None:
|
|
134
134
|
die(MISSING_MCP_EXTRA)
|
|
135
|
-
from if_cli.router.
|
|
135
|
+
from if_cli.router.log import log
|
|
136
|
+
from if_cli.router.server import build_router, run_server
|
|
136
137
|
|
|
137
138
|
timeout = parse_timeout_seconds(values["timeout"], "--timeout")
|
|
138
139
|
extra_read_only = frozenset(values["allow-tool"] or [])
|
|
@@ -18,6 +18,7 @@ from if_cli.cache import (
|
|
|
18
18
|
load_cache,
|
|
19
19
|
store_tokens,
|
|
20
20
|
)
|
|
21
|
+
from if_cli.callback_page import failure_page, state_mismatch_page, success_page
|
|
21
22
|
from if_cli.config import Profile, meaningful
|
|
22
23
|
from if_cli.constants import DEFAULT_SCOPE, LOOPBACK_HOST
|
|
23
24
|
from if_cli.http import DEFAULT_REQUEST_TIMEOUT_S, fetch_with_timeout, validate_http_url
|
|
@@ -187,7 +188,7 @@ class _CallbackServer:
|
|
|
187
188
|
self.send_header("Content-Type", "text/html; charset=utf-8")
|
|
188
189
|
self.send_header("Connection", "close")
|
|
189
190
|
self.end_headers()
|
|
190
|
-
self.wfile.write(
|
|
191
|
+
self.wfile.write(state_mismatch_page())
|
|
191
192
|
return
|
|
192
193
|
code = params.get("code")
|
|
193
194
|
self.send_response(200)
|
|
@@ -195,12 +196,12 @@ class _CallbackServer:
|
|
|
195
196
|
self.send_header("Connection", "close")
|
|
196
197
|
self.end_headers()
|
|
197
198
|
if code:
|
|
198
|
-
body =
|
|
199
|
+
body = success_page()
|
|
199
200
|
else:
|
|
200
201
|
error = escape_html(params.get("error") or "")
|
|
201
202
|
description = escape_html(params.get("error_description") or "")
|
|
202
|
-
body =
|
|
203
|
-
self.wfile.write(body
|
|
203
|
+
body = failure_page(error, description)
|
|
204
|
+
self.wfile.write(body)
|
|
204
205
|
callback.result = params
|
|
205
206
|
|
|
206
207
|
return Handler
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def log(message: str) -> None:
|
|
7
|
+
"""Write one diagnostic line to stderr.
|
|
8
|
+
|
|
9
|
+
The router speaks MCP over stdout, so stderr is the only channel that can
|
|
10
|
+
carry anything to the operator. This lives in its own module because both
|
|
11
|
+
`server` and `upstream` write to it and `server` imports `upstream`.
|
|
12
|
+
"""
|
|
13
|
+
sys.stderr.write(f"[if-cli mcp] {message}\n")
|
{insightfactory_cli-1.0.3.dev19 → insightfactory_cli-1.0.3.dev21}/src/if_cli/router/server.py
RENAMED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
-
import sys
|
|
5
4
|
from dataclasses import dataclass
|
|
6
5
|
from importlib.metadata import version
|
|
7
6
|
from typing import Any
|
|
@@ -15,6 +14,7 @@ from mcp.server.stdio import stdio_server
|
|
|
15
14
|
from if_cli.config import Profile
|
|
16
15
|
from if_cli.router import catalog, policy
|
|
17
16
|
from if_cli.router.catalog import ENV_ARG, EnvironmentSpec
|
|
17
|
+
from if_cli.router.log import log
|
|
18
18
|
from if_cli.router.upstream import Upstream
|
|
19
19
|
from if_cli.runtime import CliError
|
|
20
20
|
|
|
@@ -24,10 +24,6 @@ SERVER_VERSION = version("insightfactory-cli")
|
|
|
24
24
|
DEFAULT_CATALOG_RETRY_WINDOW_S = 5.0
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def log(message: str) -> None:
|
|
28
|
-
sys.stderr.write(f"[if-cli mcp] {message}\n")
|
|
29
|
-
|
|
30
|
-
|
|
31
27
|
def _catalog_retry_window_seconds() -> float:
|
|
32
28
|
"""Read the catalogue-rebuild retry window, in milliseconds, from the environment.
|
|
33
29
|
|